AddIdentity 与 AddIdentityCore

Posted

技术标签:

【中文标题】AddIdentity 与 AddIdentityCore【英文标题】:AddIdentity vs AddIdentityCore 【发布时间】:2019-08-17 02:17:06 【问题描述】:

在 ASP.NET Core 中,您可以添加各种服务进行识别:AddDefaultIdentityAddIdentityAddIdentityCore

AddIdentityAddIdentityCore 有什么区别?

【问题讨论】:

【参考方案1】:

AddIdentityCore 添加了用户管理操作所必需的服务,例如创建用户、散列密码等。下面是相关的source:

public static IdentityBuilder AddIdentityCore<TUser>(this IServiceCollection services, Action<IdentityOptions> setupAction)
    where TUser : class

    // Services identity depends on
    services.AddOptions().AddLogging();

    // Services used by identity
    services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
    services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
    services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
    services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
    
    // No interface for the error describer so we can add errors without rev'ing the interface
    services.TryAddScoped<IdentityErrorDescriber>();
    services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser>>();
    services.TryAddScoped<UserManager<TUser>>();

    ...

本质上,这归结为注册UserManager&lt;TUser&gt; 的实例,但首先注册其所有依赖项。注册这些服务后,您可以从 DI 中检索UserManager&lt;TUser&gt; 的实例并创建用户、设置密码、更改电子邮件等。

AddIdentity 注册与AddIdentityCore 相同的服务,但有一些额外功能:

应用程序本身、外部登录(例如 Facebook 和 Google)和 2FA 的基于 Cookie 的身份验证方案。 SignInManager,作为一种协调器,实际上位于UserManager 之上。例如,PasswordSignInAsync 使用 UserManager 检索用户、验证密码(如果已设置),然后负责创建 cookie。 AddIdentity 本身也采用 TRole 并注册支持角色所需的服务。

为了完整起见,这里是AddIdentity source:

public static IdentityBuilder AddIdentity<TUser, TRole>(this IServiceCollection services, Action<IdentityOptions> setupAction)
    where TUser : class
    where TRole : class

    // Services used by identity
    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);
    );

    // Hosting doesn't add IHttpContextAccessor by default
    services.AddHttpContextAccessor();
    
    // Identity services
    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>>();
    // No interface for the error describer so we can add errors without rev'ing the interface
    services.TryAddScoped<IdentityErrorDescriber>();
    services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
    services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
    services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
    services.TryAddScoped<UserManager<TUser>>();
    services.TryAddScoped<SignInManager<TUser>>();
    services.TryAddScoped<RoleManager<TRole>>();

    ...

【讨论】:

核心模块更快吗? 这与性能无关。任何一个都使用具有相同性能的相同内核。但是,如果您加载更多功能,则初始化时间会稍长一些,并且会占用更多内存。

以上是关于AddIdentity 与 AddIdentityCore的主要内容,如果未能解决你的问题,请参考以下文章

AddIdentity() 失败“InvalidOperationException:方案已存在:Identity.Application”

<mat-tab> 角材质内的 routerLink

IdentityServer4实战 - 与API单项目整合

如何读取 JSch 命令输出?

java在程序结束时挂起

GetExternalLoginInfoAsync 始终返回 null Azure AD