AuthenticationManager【转】

在之前写过一篇关于 ASP.NET Core 中间件的文章,里面有一部分(怎么样自定义自己的中间件)是具体关于认证系统的一个具体使用,有兴趣的朋友可以看一下这篇文章

AuthenticationManager

认证管理员(AuthenticationManager),在core2.0中,AuthenticationManager对象是HttpContext的一个属性(HttpContext.Authentication)

AuthenticationScheme:验证方案名称

public abstract class AuthenticationManager:IAuthenticationHandler
{
    //AuthenticateContext包含了需要认证的上下文
    public abstract Task AuthenticateAsync(AuthenticateContext context);
    
    //握手
    public abstract Task ChallengeAsync(string authenticationScheme, AuthenticationProperties properties, ChallengeBehavior behavior);
    
    //登入
    public abstract Task SignInAsync(string authenticationScheme, ClaimsPrincipal principal, AuthenticationProperties properties);
    
    //登出
    public abstract Task SignOutAsync(string authenticationScheme, AuthenticationProperties properties);
}

认证方法,AuthenticateAsync() ,注意这是其一个核心功能

然后还有一个握手ChallengeAsync,登入SignInAsync和登出SignOutAsync,下面说说笔者对这三个方法的理解吧。

ChallengeAsync:是社区协议文件 RFC2167 定义的关于在HTTP Authentication 过程中的一种关于握手的一个过程,主要是摘要认证(digest authentication)。

IAuthenticationHandler:

这个接口是在 AuthenticationManager 实现类 DefaultAuthenticationManager 中延伸出来的,所以大家不用再去看里面的源码了,记住以后如果需要重写认证相关的东西,实现IAuthenticationHandler就可以了。

Authentication 中间件

对 IAuthenticationHandler 的初步实现,封装了 AuthenticationHandler 这个抽象类,把具体的核心功能都交给下游去实现了,下面的CookieAuthentication 中间件核心类 CookieAuthenticationHandler 就是继承自AuthenticationHandler, 知道这么多就够了。

CookieAuthentication 中间件

 以下是 CookieAuthentication 中间件中的核心类 CookieAuthenticationHandler 的里面的核心方法HandleAuthenticateAsync(),同样你可以理解为实现的 IAuthenticationHandler 接口的 AuthenticateAsync:

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    // 解析
    var result = await EnsureCookieTicket();
    if (!result.Succeeded)
    {
        return result;
    }

    //进行验证
    var context = new CookieValidatePrincipalContext(Context, result.Ticket, Options);
    await Options.Events.ValidatePrincipal(context);

    if (context.Principal == null)
    {
        return AuthenticateResult.Fail("No principal.");
    }

    if (context.ShouldRenew)
    {
        RequestRefresh(result.Ticket);
    }
    
    // 验证通过
    return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Options.AuthenticationScheme));
}

HandleSignInAsync

组装 Cookie 登入上下文信息,写入到 Http 流的 header 中,也就写入到了客户端浏览器cookie。

至此,整个过程就完了,我们来看一下代码:


//方法里面的流程,我只列出了核心部分,影响阅读的全删了
protected override async Task HandleSignInAsync(SignInContext signin)
{
    // 解析
    var result = await EnsureCookieTicket();
    
    // 组织登入上下文,设置过期时间等
    // 使用 data protected 加密登记本上的信息
    var cookieValue = Options.TicketDataFormat.Protect(ticket);

    // 写入到浏览器header
    await ApplyHeaders(cookieValue);
}

还记得前面 HttpContext 中的ClaimsPrincipal User吗? 现在有值了。至此,CookieAuthentication 中间件的整个工作流程已经讲完了,故事也结束了。

以上,就是这两行代码背后的故事:

var user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "奥巴马") }, CookieAuthenticationDefaults.AuthenticationScheme));
await HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);

总结

在本篇中我们知道了 AuthenticationManager,也知道了 IAuthenticationHandler 并且简单的介绍了一下 Authentication 中间件和 CookieAuthentication 中间件,其中 CookieAuthentication 中间件是我们以后使用最多的一个中间件了,本篇也对其做了一个详细的介绍,我想通过本篇文章在以后使用的过程中应该问题不大了。

有同学可能会问了,讲了这么多认证的东西它和 Identity 有什么关系呢? 难道我通篇都在隐藏他和 Identity 的关系你没看出来?。。。。真的想知道? 看下一篇吧。


原文地址:https://www.cnblogs.com/fanfan-90/p/12067332.html