在之前写过一篇关于 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 的关系你没看出来?。。。。真的想知道? 看下一篇吧。