Author : MD TAREQ HASSAN | Updated : 2021/07/11
Ways To Authenticate
- ASP.Net Core Identity (IdentityBbContext, IdentityUser, EF Core Code First Migration etc.)
 - OpenID Connect
    
- Microsoft Identity Platform (Microsoft Identity Web)
 - Okta
 - etc.
 
 - IdentityServer4 (Open source OpenID Connect provider)
 - Platform Level Authentication
    
- Azure App Service Easy Auth
 - Azure AKS Easy Auth
 - Azure API Management Authentication
 
 
Things You Should Know
- ASP.Net core Identity
 - What is Json Web Token (JWT)
 - What is OAuth 2.0
 - What is OpenID Connect?
 - OpenID Connect Providers
 
Microsoft Identity Platform
- New version of “Azure AD for developers”
 - Unified platform to implement OpenID Connect using Azure AD
 
Microsoft Identity Web
- Implementation of Microsoft Identity Platform for ASP.Net
 - In other words, implementation of OpenID Connect using Azure AD for ASP.Net
 
Asp.Net Core Identity
- Authentication and Authoriztion Framework that comes with .Net Framework
 - Uses Entity Framework Core Code First migration
 - Also provides UIs for managing user information and login functionality
 
See: Scaffolding default implementation or Asp.Net Core Identity
Configurations in Startup
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // services for Identity
    services.AddDbContextPool<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
	
    // Identity for app
    services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddControllersWithViews();
    services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	// ... ... ...
	app.UseRouting();
	app.UseAuthentication();
	app.UseAuthorization();
	app.UseEndpoints(endpoints =>
	{
		endpoints.MapControllerRoute(
			name: "default",
			pattern: "{controller=Home}/{action=Index}/{id?}"
		);
		endpoints.MapRazorPages();
	});
}
Extending default identity implementation
- Visual Studio templates creates 
ApplicationUseris which is an implementation ofIdentityUser- It’s meant to simplify the extension of the user object
 - it doesn’t actually add anything
 - because it hides all of the generic properties, it can cause some confusion when using other parts of the library
 
 - It is perfectly acceptable to use IdentityUser directly
 - Links:
 
We are gonna extend default implementation and add properties according to our need.
First of all: Scaffold default identity implementation
ApplicationUser.cs
//
// extending default implemention of IdentityUser<TKey>
// class IdentityUser: IdentityUser<string> { }
//
public class ApplicationUser : IdentityUser
{
    public string CustomTag { get; set; }
}
ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options)
    {
	
    }
}
AddDefaultIdentity vs AddIdentity
- Roles is the only real difference between the two
    
AddDefaultIdentity: removes roles, use when you do not need rolesAddIdentity: use when you need roles
 - AddDefaultIdentity was introduced in ASP.NET Core 2.1. Calling AddDefaultIdentity is similar to calling the following:
    
- AddIdentity
 - AddDefaultUI
 - AddDefaultTokenProviders
 - See: AddDefaultIdentity<TUser> implementation code at Github
 
 - To add role when using AddDefaultIdentity: 
services.AddDefaultIdentity<ApplicationUser>().AddRoles<ApplicationRole>() - Links:
 
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
	services.AddDbContextPool<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
	
	services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
	    .AddEntityFrameworkStores<ApplicationDbContext>();
	services.AddControllersWithViews();
	services.AddRazorPages();
}
Replace IdentityUser with ApplicationUser in Views/Shared/_LoginPartial.cshtml
@using Microsoft.AspNetCore.Identity
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager
Notes:
IUserStore<TKey>is used byUserManager<TKey>UserManager<TKey>is used bySignInManager<TKey>- Custom property 
CustomTagadded to IdentityUser, so we need to create migration and update database (EF Core will create table column forCustomTag) - PMC:
    
Add-Migration AddCustomTagUpdate-Database
 
Change the primary key type of ApplicationUser
A change to the PK column’s data type after the database has been created is problematic on many database systems. Changing the PK typically involves dropping and re-creating the table. Therefore, key types should be specified in the initial migration when the database is created.
ApplicationUser.cs
//
// extending IdentityUser<TKey>
// TKey => Guid
//
public class ApplicationUser : IdentityUser<Guid>
{
    public string CustomTag { get; set; }
}
ApplicationRole.cs
public class ApplicationRole : IdentityRole<Guid>
{
    public string Description { get; set; }
}
ApplicationDbContext.cs
using System;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options)
    {
	
    }
}
We need to use AddIdentity instead of AddDefaultIdentity (because AddDefaultIdentity does have role).  
Also should call .AddDefaultUI() & .AddDefaultTokenProviders()
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
	services.AddDbContextPool<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
	
	services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.SignIn.RequireConfirmedAccount = true)
	    .AddEntityFrameworkStores<ApplicationDbContext>()
		.AddDefaultUI()
		.AddDefaultTokenProviders();
	services.AddControllersWithViews();
	services.AddRazorPages();
}
See: Add navigation properties
Custom Implementation
// Uses all the built-in Identity types
// Uses `string` as the key type
public class IdentityDbContext: IdentityDbContext<IdentityUser, IdentityRole, string>
{
}
// Uses the built-in Identity types except with a custom User type
// Uses `string` as the key type
public class IdentityDbContext<TUser>: IdentityDbContext<TUser, IdentityRole, string> where TUser : IdentityUser
{
}
// Uses the built-in Identity types except with custom User and Role types
// The key type is defined by TKey
public class IdentityDbContext<TUser, TRole, TKey> : IdentityDbContext<TUser, TRole, TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>, IdentityUserLogin<TKey>, IdentityRoleClaim<TKey>, IdentityUserToken<TKey>>
        where TUser : IdentityUser<TKey>
        where TRole : IdentityRole<TKey>
        where TKey : IEquatable<TKey>
{
}
// No built-in Identity types are used; all are specified by generic arguments
// The key type is defined by TKey
public abstract class IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>: IdentityUserContext<TUser, TKey, TUserClaim, TUserLogin, TUserToken>
         where TUser : IdentityUser<TKey>
         where TRole : IdentityRole<TKey>
         where TKey : IEquatable<TKey>
         where TUserClaim : IdentityUserClaim<TKey>
         where TUserRole : IdentityUserRole<TKey>
         where TUserLogin : IdentityUserLogin<TKey>
         where TRoleClaim : IdentityRoleClaim<TKey>
         where TUserToken : IdentityUserToken<TKey>
{
}
You can extend any Entity/IdentityModel and use it in application uisng overloads of IdentityDbContext (ApplicationDbContext)
services.AddDbContextPool<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
	.AddEntityFrameworkStores<ApplicationDbContext>();
Example: Custom storage providers for ASP.NET Core Identity
Azure App Service Easy Auth
See: Azure app service easy auth in Blazor