• 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 的关系你没看出来?。。。。真的想知道? 看下一篇吧。


  • 相关阅读:
    VI中的批量替换--转载
    Zookeeper集群
    Zookeeper实现Master选举(哨兵机制)
    分布式session之token解决方案实现
    浏览器
    分布式session之redis解决方案实现
    服务器操作常用
    Nginx安装教程(Centos6.8)
    分布式锁(Redis实现)
    开发总结
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/12067332.html
Copyright © 2020-2023  润新知