AddIdentityCore,AddIdentity,AddDefaultIdentity的区分

Asp.Net Core中有三种方式可以添加身份验证中间件,分别是:

1、AddIdentityCore

2、AddIdentity

3、AddDefaultIdentity

差异记录如下:

AddIdentityCore

顾名思义,只添加最核心的相关中间件,查看代码可以发现,它添加了如下:

services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services.TryAddScoped<IUserConfirmation<TUser>, DefaultUserConfirmation<TUser>>();
services.TryAddScoped<IdentityErrorDescriber>();
services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser>>();
services.TryAddScoped<UserManager<TUser>>();

以上只包括了Identity最最基础的相关类,并不包含任何身份验证有关系的部分。

如果用这个的话,那就需要自己添加身份验证、权限验证的中间件。

AddIdentity

这个比AddIdentityCore多了很多内容,它默认会启用基于Cookie的身份验证中间件,并且增加了关于Role的相关类,具体代码如下:

services.AddAuthentication(options =>
{
	options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
	options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
	options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddCookie(IdentityConstants.ApplicationScheme, o =>
{
	o.LoginPath = new PathString("/Account/Login");
	o.Events = new CookieAuthenticationEvents
	{
		OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
	};
})
.AddCookie(IdentityConstants.ExternalScheme, o =>
{
	o.Cookie.Name = IdentityConstants.ExternalScheme;
	o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
})
.AddCookie(IdentityConstants.TwoFactorRememberMeScheme, o =>
{
	o.Cookie.Name = IdentityConstants.TwoFactorRememberMeScheme;
	o.Events = new CookieAuthenticationEvents
	{
		OnValidatePrincipal = SecurityStampValidator.ValidateAsync<ITwoFactorSecurityStampValidator>
	};
})
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
	o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
	o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});

services.AddHttpContextAccessor();
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
services.TryAddScoped<IdentityErrorDescriber>();
services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
services.TryAddScoped<IUserConfirmation<TUser>, DefaultUserConfirmation<TUser>>();
services.TryAddScoped<UserManager<TUser>>();
services.TryAddScoped<SignInManager<TUser>>();
services.TryAddScoped<RoleManager<TRole>>();

相对而言,这个已经比较全面了,只是需要再添加相关UI即可。

AddDefaultIdentity

这是新增的一个方法,最主要的作用是,它将默认的UI页也加载进来,我们无需再自定义。它的代码如下:

services.AddAuthentication(o =>
{
	o.DefaultScheme = IdentityConstants.ApplicationScheme;
	o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies(o => { });

return services.AddIdentityCore<TUser>(o =>
{
	o.Stores.MaxLengthForKeys = 128;
	configureOptions?.Invoke(o);
})
	.AddDefaultUI()
	.AddDefaultTokenProviders();

可以看到,首先添加一个Cookie身份验证中间件进来,其次在AddIdentityCore基础上,增加DefaultUI和DefaultTokenProviders。

在AddDefaultUI中,我们又可以看到它添加了Mvc的支持:

builder.AddSignInManager();
builder.Services
	.AddMvc()
	.ConfigureApplicationPartManager(apm =>
	{
		// We try to resolve the UI framework that was used by looking at the entry assembly.
		// When an app runs, the entry assembly will point to the built app. In some rare cases
		// (functional testing) the app assembly will be different, and we'll try to locate it through
		// the same mechanism that MVC uses today.
		// Finally, if for some reason we aren't able to find the assembly, we'll use our default value
		// (Bootstrap5)
		if (!TryResolveUIFramework(Assembly.GetEntryAssembly(), out var framework) &&
			!TryResolveUIFramework(GetApplicationAssembly(builder), out framework))
		{
			framework = default;
		}

		var parts = new ConsolidatedAssemblyApplicationPartFactory().GetApplicationParts(typeof(IdentityBuilderUIExtensions).Assembly);
		foreach (var part in parts)
		{
			apm.ApplicationParts.Add(part);
		}
		apm.FeatureProviders.Add(new ViewVersionFeatureProvider(framework));
	});

builder.Services.ConfigureOptions(
	typeof(IdentityDefaultUIConfigureOptions<>)
		.MakeGenericType(builder.UserType));
builder.Services.TryAddTransient<IEmailSender, EmailSender>();

综上,推荐选择用AddIdentity这个,可以自定义UI,也包含了基本的身份验证。