一.登录分析

  在使用identity身份验证登录时,在login中调用的方法是:

  var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);

  跟踪查看源码,源码下载https://github.com/aspnet/AspNetCore/releases 这里有core源码的不同版本,在vs 2017下只能加载2.2及以下的版本。

  下面是登录的大概步骤:

  (1) 检查用户名是否存在(UserManager.cs在Microsoft.AspNetCore.Identity.core源码中)

    var user = await UserManager.FindByNameAsync(userName);

  (2) UserManager类来检查用户名和密码是否存在

    UserManager.CheckPasswordAsync(user, password)

  (3) 登录,isPersistent是指浏览器关闭后登录cookie是否应该保持,如果是true则永久保存cookie,如果为false则使用services.ConfigureApplicationCookie中options.ExpireTimeSpan 来重写。SignInOrTwoFactorAsync(user, isPersistent)方法最终调用SignInAsync进行登录。

       public virtual async Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, string authenticationMethod = null)
{
var userPrincipal = await CreateUserPrincipalAsync(user);
// Review: should we guard against CreateUserPrincipal returning null?
if (authenticationMethod != null)
{
userPrincipal.Identities.First().AddClaim(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod));
}
await Context.SignInAsync(IdentityConstants.ApplicationScheme,
userPrincipal,
authenticationProperties ?? new AuthenticationProperties());
}

    AuthenticationProperties:用来存储身份认证会话

    IdentityConstants:是配置Identity系统使用的cookie中间件的所有选项, ApplicationScheme属性是指:该方案运用于Identity应用程序的cookies(默认方案)。如下所示:

          private static readonly string CookiePrefix = "Identity";
public static readonly string ApplicationScheme = CookiePrefix + ".Application"

    登录涉及到三个类ClaimsPrincipal(声明当事人)、ClaimsIdentity(声明标识)、Claim(声明)。

    Claim:是名称值对,比如名称ClaimType:身份证, 值ClaimValue:18位号码。

    ClaimsIdentity:一组Cliams 就构成了一个Identity标识。

    ClaimsPrincipal:当事人可以持有多个ClaimsIdentity标识。

    最后SignInAsync 创建一个加密的 cookie,并将其添加到当前响应。

二.注销

  若要注销(退出登录)当前用户,然后删除其 cookie,需要调用SignOutAsync 。

    await HttpContext.SignOutAsync();    

三. Identity表管理

  3.1可以使用UserManager类和RoleManager类来管理Identity表,可以参考"通过授权创建web应用",下面是声明的新增方法

    //添加用户声明 Microsoft.AspNetCore.Identity.UserManager<TUser>
public virtual Task<IdentityResult> AddClaimAsync(TUser user, Claim claim) //添加角色声明 Microsoft.AspNetCore.Identity.RoleManager<TRole>
public virtual async Task<IdentityResult> AddClaimAsync(TRole role, Claim claim)

  3.2 在UserManager下,会发现很多方法,都是传入ClaimsPrincipal参数,如下所示:

    //获取用户ID
GetUserId(ClaimsPrincipal principal)
//获取用户
Task<TUser> GetUserAsync(ClaimsPrincipal principal)

    可以通过如下来转换成ClaimsPrincipal:

    ClaimsPrincipal principal = HttpContext.Current.User as ClaimsPrincipal;

  3.3 Claim声明类

    声明值Value:对于简单的声明值可以使用字符串存储,更复杂的值类型,建议使用标准的 XML (或json)架构类型,在应用程序端序列化和反序列化。

    声明类型Type:标识值的类型信息。

    其它属性, 如定义颁发声明等,参考官方文档

    

四.不使用identity系统进行身份认证

  如果开发想自定义用户表,角色表等,完全抛弃identity系统,实现参考"使用cookie 而无需ASP.NET Core 标识的身份验证

五. Identity扩展

  (1) 如果想使用不同数据访问方法,不使用默认的EF Core。

  (2) 如果不想使用 SQL Server存储用户信息,想使用其它数据存储。

  (3) 对Identity表想使用不同的结构。

  实现参考"ASP.NET Core标识的自定义的存储提供程序

    

六. Identity配置

  对于 ASP.NET Core Identity设置,例如密码策略、 锁定和 cookie 配置使用默认值等。参考文档 "配置标识"

    

七. 帐户确认和 ASP.NET Core 中的密码恢复

  https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/accconfirm?view=aspnetcore-2.2&tabs=visual-studio  

    

04-24 17:13