话题背景

关于认证我的个人理解是,验证信息的合法性。在我们生活当中,比如门禁,你想进入一个有相对安全措施的小区或者大楼,你需要向保安或者门禁系统提供你的身份信息证明,只有确定你是小区业主,才可以进来,我这只是打个比方啊,不要纠结。对于我们计算机的安全领域,认证其实也非常类似,windows系统登陆就是一个很好的例子。今天我们主要学习的是ASPNET以及ASPNETCORE平台上面一些主流的认证方式。

正式话题-认证

我最开始接触NET平台的WEB框架是从APSNETWEBFORM开始->ASPNETMVC->ASPNETMVCCORE,下面我们就从WEBFORM开始吧(包括MVC1.x-4.x)。在MVC5之前,我们常用的认证方式有,Forms、Windows、Passport、None这三种认证方式,严格意义上说是三种,None为不认证,而在这三种认证方式当中,我们最常用的就是Forms表单认证,下面我们一起来看看Forms表单认证的实现原理。

Forms表单认证

我会以我自己的使用方式介绍再到实现原理。整个Forms认证的实现逻辑大概是,说到Forms认证我们就不得不说ASPNET处理管道,为什么这么说呢?因为ASPNET的很多基础功能都是通过相应的HttpModule实现的,比如认证、授权、缓存、Session等等。ASPNET平台的Forms认证就是基于FormsAuthenticationModule模块实现,相应的Windows认证也是一样,由WindowsAuthenticationModule实现。对于Forms认证方式登录而言。

1.匹配用户名&密码是否正确。
2.构建FormsAuthenticationTicket对象。

3.通过FormsAuthentication.Encrypt方法加密Ticker信息。
4.基于加密Ticker信息,构建HttpCookie对象。
5.写入Response,输出到客户端。
以上就是我们基于Forms表单认证方式的登录实现逻辑,下面我们来梳理一下认证的大概实现逻辑,针对每次请求而言。
1.在ASPNET管道生命周期里,认证模块FormsAuthenticationModule会接管并读取Cookie。
2.解密Cookie获取FormsAuthenticationTicket对象并且验证是否过期。
3.根据FormsAuthenticationTicket对象构造FormsIdentity对象并设置HttpContext.User。
4.完成认证。
下面我们一起看看Forms认证的具体实现,我会以我自己开发过程中使用的方式加以介绍。首先我们会在web.config文件里面定义authentication配置节点,如下。

 <authentication mode="Forms">
<forms name="AUTH" loginUrl="~/login" protection="All" timeout="" path="/" requireSSL="false" slidingExpiration="true" />
</authentication>

mode属性对应了4属性值,除Forms以外还有上面我提到的三种方式。其他三种由于篇幅问题,在这里不做介绍。这些属性我相信大家应该都比较熟悉。下面我们看看关于Forms认证具体的后台代码。看代码。

 public virtual void SignIn(User user, // 这个user是你校验合法性之后的这么一个用户标识对象
bool createPersistentCookie)
{
var now = DateTime.UtcNow.ToLocalTime();
// 构建Ticker对象
var ticket = new FormsAuthenticationTicket(
,
user.Username,
now,
now.Add(_expirationTimeSpan),
createPersistentCookie,
user.Username,
FormsAuthentication.FormsCookiePath);
// 加密ticker对象
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
// 通过加密ticker对象构建HttpCookie对象
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.HttpOnly = true;
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.Path = FormsAuthentication.FormsCookiePath;
if (FormsAuthentication.CookieDomain != null)
{
cookie.Domain = FormsAuthentication.CookieDomain;
}
// 写入输出流Response
_httpContext.Response.Cookies.Add(cookie);
}

以上代码就完成了我们的Forms认证所需的Cookie信息,可能有些朋友在以往开发WebForms到4.x最常用的使用方式是FormsAuthentication.SetAuthCookie(user.UserName, true),其实SetAuthCookie里面的实现逻辑跟上面实现大同小异,只是我比较喜欢手动创建可以更多的控制一些辅助信息而已。在以上代码片段中,我着重想介绍一下FormsAuthentication.Encrypt(ticket)加密方法,因为它涉及到了Forms认证的安全机制,也好让各位朋友大概了解Forms认证到底安全不安全。FormsAuthentication该对象位于System.Web.Security名称空间下面,主要作用是安全相关辅助工具类,比如加解密等。
1.在默认情况下,ASPNETFORMS认证模块针对Ticker的加密Key是由ASPNET随机生成,并存储在本地安全机构LSA中。我们可以通过一下代码片段验证这一逻辑。

 private CryptographicKey GenerateCryptographicKey(string configAttributeName, string configAttributeValue, int autogenKeyOffset, int autogenKeyCount, string errorResourceString)
{
// 其他代码
bool flag1 = false;
bool flag2 = false;
bool flag3 = false;
if (configAttributeValue != null)
{
string str1 = configAttributeValue;
char[] chArray = new char[]{ ',' };
foreach (string str2 in str1.Split(chArray))
{
if (!(str2 == "AutoGenerate"))
{
if (!(str2 == "IsolateApps"))
{
if (!(str2 == "IsolateByAppId"))
flag3 = true;
}
else
flag2 = true;
}
else
flag1 = true;
}
}
if (flag2)
MachineKeyMasterKeyProvider.AddSpecificPurposeString((IList<string>) stringList, "IsolateApps", this.ApplicationName);
if (flag3)
MachineKeyMasterKeyProvider.AddSpecificPurposeString((IList<string>) stringList, "IsolateByAppId", this.ApplicationId);
}

以上代码片段逻辑也比较简单,自己体会吧。
2.手动指定machineKey配置节点,该配置节在web.config文件里面,其中包括可支持的加密算法,加密算法支持DES,3DES,AES等。具体代码我就不贴了,我们跟踪其实现原理意在了解Forms认证其安全性。
3.通过以上两点介绍,我个人认为Forms认证相对来说很安全。
Forms认证
下面我们看看Forms的实现原理。
ASPNET的Forms认证发生在ASPNET管道的FormsAuthenticationModule对象里面,在该对象里面的Init方法里面绑定了认证事件OnEnter,具体的认证实现是OnEnter里面调用的OnAuthenticate方法。我们来看下代码。

 private void OnAuthenticate(FormsAuthenticationEventArgs e)
{
// 其他代码
bool cookielessTicket = false;
// 从请求cookie里面抽取ticker票据信息
FormsAuthenticationTicket ticketFromCookie = FormsAuthenticationModule.ExtractTicketFromCookie(e.Context, FormsAuthentication.FormsCookieName, out cookielessTicket);
// 过期或者为null直接返回
if (ticketFromCookie == null || ticketFromCookie.Expired)
return;
FormsAuthenticationTicket ticket = ticketFromCookie;
// 如果启用滑动过期,更新过期时间
if (FormsAuthentication.SlidingExpiration)
ticket = FormsAuthentication.RenewTicketIfOld(ticketFromCookie);
e.Context.SetPrincipalNoDemand((IPrincipal) new GenericPrincipal((IIdentity) new FormsIdentity(ticket), new string[]));
if (!cookielessTicket && !ticket.CookiePath.Equals("/"))
{
cookie = e.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)
cookie.Path = ticket.CookiePath;
}
if (ticket == ticketFromCookie)
return;
if (cookielessTicket && ticket.CookiePath != "/" && ticket.CookiePath.Length > )
ticket = FormsAuthenticationTicket.FromUtc(ticket.Version, ticket.Name, ticket.IssueDateUtc, ticket.ExpirationUtc, ticket.IsPersistent, ticket.UserData, "/");
string cookieValue = FormsAuthentication.Encrypt(ticket, !cookielessTicket); if (cookielessTicket)
{
e.Context.CookielessHelper.SetCookieValue('F', cookieValue);
e.Context.Response.Redirect(e.Context.Request.RawUrl);
}
else
{
if (cookie != null)
cookie = e.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie == null)
{
cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue);
cookie.Path = ticket.CookiePath;
}
if (ticket.IsPersistent)
cookie.Expires = ticket.Expiration;
cookie.Value = cookieValue;
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.HttpOnly = true;
if (FormsAuthentication.CookieDomain != null)
cookie.Domain = FormsAuthentication.CookieDomain;
cookie.SameSite = FormsAuthentication.CookieSameSite;
e.Context.Response.Cookies.Remove(cookie.Name);
e.Context.Response.Cookies.Add(cookie);
}
}

以上代码片段反映了Forms认证具体逻辑,逻辑比较简单,我也大概做了一些注释,以上就是ASPNET在MVC5.x之前ASPNETForms认证的实现。接下来我们对ASPNET5.X之前的版本基于Forms认证做个简单的总结。
1.用户在未登录的情况下,访问我们受保护的资源。
2.FormsAuthenticationModule模块验证用户的合法性,主要是生成Identity对象和设置IsAuthenticated属性。
3.如果未登录则endrequest阶段跳转到web.config配置的登录页或者硬编码指定的登录页。
4.用户登录。
5.匹配用户名&密码,如果合法,生成ticker票据和cookie并写入response。
6.访问受保护的资源(授权部分)。
7.FormsAuthenticationModule模块验证用户的合法性。
8.如果为以认证用户IsAuthenticated=true,授权访问相应的资源。
后续的每次请求也是6,7,8循环。
针对Forms认证就此告一段落,下面我们接着介绍MVC5的常规认证方式。
MVC5Cookies认证方式
为什么我要把MVC5的认证方式单独做一个小结讲解呢?它有什么特别之处吗?没错,ASPNETMVC5引入了新的设计理念OWin,我个人的理解是,解耦webserver容器IIS和模块化。同时NET4.5也引入了ASPNET.Identity,Identity主要是提供帮助我们管理用户、角色以及存储,当然Identity相较Membership强大多了。对于OWin和Identity我在这里不做详细介绍,自己可以去搜一些帖子看或者查看官方文档。OWin在WebServers与ASPNETWebApplication之间定义了一套标准接口,其官方的开源实现是Katana这个开源项目,我们今天要介绍的MVC5的认证就是基于Katana这个开源项目的CookieAuthenticationMiddleware中间件实现的,在介绍CookieAuthenticationMiddleware中间件之前,我想简单罗列一下MVC5的cookies认证(你也可以认为是Katana实现的新的Forms认证)和我们早期使用的Forms认证做个简单的对比。
相同点:1.基于cookie认证 2.支持滑动过期策略 3.实现令牌保护 4.重定向。
不同点:Identity结合Owin实现了声明认证Claims-based。
以上是个人的一点理解,下面我们具体看看认证中间件的实现,CookieAuthenticationMiddleware的定义。

 public class CookieAuthenticationMiddleware : AuthenticationMiddleware<CookieAuthenticationOptions>
{
// 其他成员
public CookieAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, CookieAuthenticationOptions options)
: base(next, options)
{
}
// 创建具体的AuthenticationHandler
protected override AuthenticationHandler<CookieAuthenticationOptions> CreateHandler()
{
return new CookieAuthenticationHandler(_logger);
}
}

CookieAuthenticationMiddleware里面就一个方法成员,通过CreateHandler方法创建了具体的CookieAuthenticationHandler对象,我们的认证核心实现就发生在这个Handler里面。接下来我们看看CookieAuthenticationHandler对象的定义。

 internal class CookieAuthenticationHandler : AuthenticationHandler<CookieAuthenticationOptions>
{
// 其他成员
private const string HeaderNameCacheControl = "Cache-Control";
private const string HeaderNamePragma = "Pragma";
private const string HeaderNameExpires = "Expires";
private const string HeaderValueNoCache = "no-cache";
private const string HeaderValueMinusOne = "-1";
private const string SessionIdClaim = "Microsoft.Owin.Security.Cookies-SessionId"; private bool _shouldRenew;
private DateTimeOffset _renewIssuedUtc;
private DateTimeOffset _renewExpiresUtc;
private string _sessionKey; protected override async Task<AuthenticationTicket> AuthenticateCoreAsync() protected override async Task ApplyResponseGrantAsync() protected override Task ApplyResponseChallengeAsync()
}

从CookieAuthenticationHandler对象的定义来看,其实也能看出一二,主要是针对cookie的相关操作,在该对象成员里面我们需要了解一下其中的三个方法。
1.AuthenticateCoreAsync,代码我就不贴了,有兴趣的朋友可以自己查看Katana开源项目的源代码。该方法内部大概实现思路是:从IOWinContext对象获取cookie,如果对owin不怎么熟悉的话,这个context你可以把它理解为我们之前熟悉的HttpContext,然后通过解密出来的cookie字符串构造ClaimsIdentity对象并添加到OwinContext对象Request.User,最后返回AuthenticationTicket对象,该对象包装的就是当前用户信息以及相关辅助信息。
2.ApplyResponseGrantAsync,设置、更新或者删除cookie并写入response。
3.ApplyResponseChallengeAsync,授权失败,发生重定向。

 public class AuthenticationTicket
{
public AuthenticationTicket(ClaimsIdentity identity, AuthenticationProperties properties)
{
Identity = identity;
Properties = properties ?? new AuthenticationProperties();
}
// 用户信息
public ClaimsIdentity Identity { get; private set; }
// 辅助信息,比如会话、过期等
public AuthenticationProperties Properties { get; private set; }
}

下面我们一起看看在我们开发过程中的应用以及内部实现
Startup是Katana开源项目引入的一种新的模块初始化方式,其实也没什么特别的,就是相关中间件的注册以及一些默认上下文对象的初始化操作。下面我们具体看代码,我们的MVC5新的认证方式在Startup里面如何注册的。

 public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// 其他代码
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{ }
});
}
}

注册逻辑很简单,通过IAppBuilder的扩展方法UseCookieAuthentication实现,接下来我们看看UseCookieAuthentication扩展方法的内部实现。

 public static IAppBuilder UseCookieAuthentication(this IAppBuilder app, CookieAuthenticationOptions options, PipelineStage stage)
{
if (app == null)
{ }
// 注册
app.Use(typeof(CookieAuthenticationMiddleware), app, options);
// 加入owin管道
app.UseStageMarker(stage);
return app;
}

整个注册逻辑就这么几行代码,相关方法都有注释。最后在程序初始化过程中通过Build方法完成Owin管道所有中间件的初始化工作。接下来我们看看具体的登录实现。

 public async Task<ActionResult> Login(LoginModel model,string returnUrl)
{
// 其他代码
if (ModelState.IsValid)
{
AppUser user = await UserManager.FindAsync(model.Name, model.Password);
if (user==null)
{
ModelState.AddModelError("","无效的用户名或密码");
}
else
{
var claimsIdentity =
await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthManager.SignIn(new AuthenticationProperties {IsPersistent = false}, claimsIdentity);
return Redirect(returnUrl);
}
} return View(model);
}

通过以上代码片段就完成了我们系统的登录操作,在以上Login方法里面,我们需要注意这么几个方法。
1.FindAsync主要是通过Identity实现用户名和密码的匹配。
2.CreateIdentityAsync主要是创建ClaimsIdentity对象,该对象后续会写入cookie。
3.SignIn包装CreateIdentity方法创建的ClaimsIdentity以及ClaimsPrincipal对象,为cookie写入Response提供相关认证信息,只有在设置cookie阶段才会写入response。
接下来我们针对Katana里面的cookie认证做个简单的总结。
1.用户在未登录的情况下,访问我们受保护的资源。
2.CookieAuthenticationMiddleware中间件验证用户的合法性。
3.用户登录。
4.匹配用户名&密码,如果合法,包装相关认证信息。
5.创建\更新cookie写入response。
6.访问受保护的资源。
7.CookieAuthenticationMiddleware中间件解密cookie验证用户认证信息。
8.如果为以认证用户,授权访问相应的资源。
后续的每次请求也是6,7,8循环。
以上MVC5新的Cookies认证方式就此告一段落,下面我们接着介绍ASPNET.Identity三方认证。
三方认证
在我们介绍三方认证之前,我们不妨先来了解一下什么是Claim,大家把它翻译成声明,我也就这么跟着叫把。Claim所描述的是一个用户单一的某个信息,比如用户名,只有多个Claim组合才能描述一个完整的用户ClaimsIdentity对象。个人理解这是一种通用的信息存储结构,一种规范,可以很方便的基于用户数据信息驱动认证和授权并且提供独立服务,各自都不需要关心自己的实现。在我们传统的认证windows或者forms认证方式中,每个系统都有自己认证方式、授权和用户数据信息,如果是几年以前,可能没有什么问题,但是在如今飞速发展的互联网时代,就显的有很大的局限性、扩展性以及安全性。接下来我们要介绍的就是MVC5基于ASPNET.Identity结合Katana实现的三方认证,也就是我们上面说的基于Claims-based实现第三方认证,这里我们以google认证为例,由于网络问题这里我们以木宛城主大拿的实例代码做示例,我会结合实例代码分析内部实现。
首先我们需要添加google服务认证中间件。

 app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
// 以下为客户端凭据,可以通过google认证服务注册
ClientId = "",
ClientSecret = "",
});

其二我们需要设计实现登录逻辑,通常情况下我们在登录论坛的时候,旁边可能会有基于QQ登录或者别的三方认证提供商。

 public ActionResult GoogleLogin(string returnUrl)
{ // 创建AuthenticationProperties对象,我们可以理解为认证复制信息字典
var properties = new AuthenticationProperties
{
RedirectUri = Url.Action("GoogleLoginCallback",
new { returnUrl = returnUrl })
};
// 初始化google认证相关辅助信息
HttpContext.GetOwinContext().Authentication.Challenge(properties, "Google");
// 返回401
return new HttpUnauthorizedResult();
}

以上代码比较简单,我也做了相应的注释,其逻辑是初始化google认证的一些辅助信息,然后返回401状态码,继而重定向到google登录页。下面我们看看登录成功之后的代码逻辑。

 public async Task<ActionResult> GoogleLoginCallback(string returnUrl)
{
// 从google认证服务获取claims
ExternalLoginInfo loginInfo = await AuthManager.GetExternalLoginInfoAsync();
// 检查该用户是否首次登录系统
AppUser user = await UserManager.FindAsync(loginInfo.Login);
if (user == null)
{
user = new AppUser
{
Email = loginInfo.Email,
UserName = loginInfo.DefaultUserName,
City = Cities.Shanghai,
Country = Countries.China
};
// 持久化用户数据
IdentityResult result = await UserManager.CreateAsync(user);
// 缓存
result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login);
}
ClaimsIdentity ident = await UserManager.CreateIdentityAsync(user,
DefaultAuthenticationTypes.ApplicationCookie);
ident.AddClaims(loginInfo.ExternalIdentity.Claims);
// 创建用户ClaimsIdentity对象
AuthManager.SignIn(new AuthenticationProperties
{
IsPersistent = false
}, ident);
return Redirect(returnUrl ?? "/");
}

以上就是三方认证的实现方式,下面我们通过Katana源码看看三方认证的实现原理。通过上面Katana的cookies认证,我们了解到认证中间件的认证逻辑是实现在相应的AuthenticationHandler里面,我们同样以google为例,去看看内部的实现。下面我们一起来上面注册的认证中间件GoogleOAuth2AuthenticationMiddleware的定义。

 public class GoogleOAuth2AuthenticationMiddleware : AuthenticationMiddleware<GoogleOAuth2AuthenticationOptions>
{
// 其他成员
public GoogleOAuth2AuthenticationMiddleware(
OwinMiddleware next,
IAppBuilder app,
GoogleOAuth2AuthenticationOptions options)
: base(next, options);
// 构建认证handler
protected override AuthenticationHandler<GoogleOAuth2AuthenticationOptions> CreateHandler()
{
return new GoogleOAuth2AuthenticationHandler(_httpClient, _logger);
}
// 构建httpclienthandler
private static HttpMessageHandler ResolveHttpMessageHandler(GoogleOAuth2AuthenticationOptions options);
}

根据以上代码片段我们了解到,GoogleOAuth2AuthenticationMiddleware中间件似乎比我们常规的cookies认证多了一个方法ResolveHttpMessageHandler,其实这个方法没有别的套路,就是辅助创建httpclient对象,完成http请求而已,在handler的认证逻辑里面需要获取googletoken,就是通过它来获取的。
第二个方法CreateHandler返回的GoogleOAuth2AuthenticationHandler对象就是我们接下来要重点讨论的对象。

 internal class GoogleOAuth2AuthenticationHandler : AuthenticationHandler<GoogleOAuth2AuthenticationOptions>
{
private const string TokenEndpoint = "https://accounts.google.com/o/oauth2/token";
private const string UserInfoEndpoint = "https://www.googleapis.com/plus/v1/people/me";
private const string AuthorizeEndpoint = "https://accounts.google.com/o/oauth2/auth"; private readonly ILogger _logger;
private readonly HttpClient _httpClient; public GoogleOAuth2AuthenticationHandler(HttpClient httpClient, ILogger logger)
{
_httpClient = httpClient;
_logger = logger;
}
// 通过httpclient访问google认证服务器获取token,根据token数据包装Claim
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync();
// 如果未认证,401授权失败发生重定向
protected override Task ApplyResponseChallengeAsync(); public override async Task<bool> InvokeAsync()
{
return await InvokeReplyPathAsync();
}
// 调用signin,保存用户信息
private async Task<bool> InvokeReplyPathAsync();
}

代码比较长,我把具体实现删掉了,实现逻辑我注释到了方法上面,有兴趣的朋友可以自己多看看源码。以上就是NET平台上面一些主流的认证方式和实现原理。接下来我们继续介绍ASPNETCORE的认证。

ASPNETCORE认证
熟悉微软web平台认证授权体系的朋友应该知道,不管是早期的Forms还是Katana的cookies甚至是我接下来要介绍的ASPNETCORE基于cookies认证,其实整体的设计逻辑大致都差不多,只是具体实现上的区别,尤其是OWin的设计理念,当然现在我们几乎已经模糊了OWin的慨念,但是在ASPNETCORE平台上到处都有它的缩影。下面我们一起来看看ASPNETCOREMVC的认证机制。
在这里,整个认证逻辑我就直接用一张图展示:

aaarticlea/png;base64,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/TbaaKPDDz9cjxnrfrgjJO0w8oIavWokk15YigT1Rggsb3nLWxhu0IkCd91116RJk7DRZ1FnTZv1srPUSyPD1UsjQXh1p1G6kKoYq/npVSPD6YWlSFAvQ8hMvEl44mVU5KE3iUq88THeyWSseoGDkHgZFeTwdlFJ5td2aWSF6qUxqZlVaThwsWYlMLMa2QS9bEtB1kuCemkkCC9rpj0AY1kVAQhFr4bTq0aE4yO+LdWbEOhlVdoocMTSm4QzM6PYKJhja2L4ZZ1gfIwXCQSveRoRSCYAm5hAjZq2OkGZzKDGLFYjowyGT4GHH374nHPOOfPMM//xj3+8853v3HrrrZNjzJ4J1Y2aLRulBOMuKnDZZZfdcMMNN9544worrPDxj3+81czZzsoam2bORnVo1EazqZRAnGVmjQwByBKyRo0ibsrMEnptrJ6fB6JAw4kJwCQmUGNZKrUTMwMBXQBqVEwOjQRlUVmCGos5k1RFQjZco5RATNA50zv21mDHXp43BkUFGuzYe8kll5x44on4kcP1o7e+9a0f+9jHfv7zn7/5zZlLqP3c0xMFF4/CljYUWH/99XfYYYc77rjj61//+kknnfSVr3xlk002yebpZ/9qAW7XauCbR0Ug9rlBKQA6USPzha6pja1A7RS4++6799xzz3nnnXfHHXe89tprX3rppdlnn/3zn//8j3/84+wIpnYH6IJVgfe///233HILJtgmT568wQYbXHXVVeo1tgJWYLgV8CBmuPt3tI7u5ptvnn/++Zdbbrnvfve7Tz311JNPPonjn2222Q455JBjjz12tLQYsaPFIOb3v//9pptuuuuuu2688ca/+c1vRkwAH64VGFEFPIgZ0Y4fysN+8MEHMXbB1Muzzz4bB4j1XxtuuOHcc8990003xZhmKA+8ykFBCryUWfw4nfIGjvIHE+tR4OrStGnTcJlp22233WyzzdDpg1mzq7ICVqBbCngQ0y0lnWf8FfjsZz+La0krrrgir0Pj+tE73vGOX//617gvadlll8U8zYc//OEvfOELRx11FFbM3HnnnS+//PL41937CvBLj5V0eOlPPj5qy9P9b7CEV0OUPyA4OQpUtcsuuzzwwANrrLHG5ptvvuWWW956660DUqrLsAJWoOsKeBDTdUmdcDwVeM973oMfrc997nMYu6AOLOnFIolzzz0Xi2P++te/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" alt="bc263adafb8c7357f96a22a574c6f4d9.png" />

画图工具是网上在线编辑的,画的不好,别见怪。下面我简单解释一下认证授权流程图,以cookies认证为例。
1.认证中间件调用CookieAuthenticationHandler实现认证,如果认证成功设置HttpContext.Use对象。
2.在执行controller中的action之前,执行授权filter,如果有设置授权filter特性。
3.如果controller或者action上没有授权filter,直接执行action,呈现view。
4.如果有定义授权filter特性,授权过滤器再次检查用户是否认证,并且合并Claim,因为可以指定多个认证scheme,认证阶段使用的是默认的sheme。
5.认证失败,授权filter设置context.Result为Challenge,在后续cookie认证中间件会发生重定向到login页面。
6.认证成功,授权失败,授权filter设置context.Result为Forbid,在后续cookie认证中间件会发生重定向到权限不足页面。
7.认证、授权都通过,最后显示view。
以上就是ASPNETCOREMVC认证授权的主要执行逻辑。接下来我们一起看看,基于COREMVC的cookies认证的应用以及内部实现。
熟悉ASPNETCORE平台开发的朋友应该知道,基础功能模块的配置初始化,一般分为两部曲,注册服务、配置中间件。当然这少不了NETCORE内置DI容器的功劳,我们将要介绍的认证系统也不例外。下面我们具体看看认证系统的配置,通过Startup类型配置,关于startup的提供机制可以看看我上一篇博客,有详细介绍。
第一部曲服务配置

 public static void AddAuthentication(this IServiceCollection services)
{ // 其他代码
var authenticationBuilder = services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = AuthenticationDefaults.AuthenticationScheme;
options.DefaultScheme = AuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = AuthenticationDefaults.ExternalAuthenticationScheme;
})
.AddCookie(AuthenticationDefaults.AuthenticationScheme, options =>
{
options.Cookie.Name = $"{CookieDefaults.Prefix}{NopCookieDefaults.AuthenticationCookie}";
options.Cookie.HttpOnly = true;
options.LoginPath = AuthenticationDefaults.LoginPath;
options.AccessDeniedPath = AuthenticationDefaults.AccessDeniedPath;
})
.AddCookie(AuthenticationDefaults.ExternalAuthenticationScheme, options =>
{
options.Cookie.Name = $"{CookieDefaults.Prefix}{CookieDefaults.ExternalAuthenticationCookie}";
options.Cookie.HttpOnly = true;
options.LoginPath = AuthenticationDefaults.LoginPath;
options.AccessDeniedPath = AuthenticationDefaults.AccessDeniedPath;
});
}

以上代码片段就完成了cookies认证的所需服务注册。其实际就是注册cookies认证所需的基础对象和辅助配置信息到DI容器,以便中间件可以通过DI容器方便获取。AddAuthentication扩展方法,主要是注册认证系统所需基础对象。AddCookie扩展方法主要是注册具体cookie认证Handler对象以及通过options模式配置辅助信息。
第二部曲中间件注册

 public static void UseAuthentication(this IApplicationBuilder application)
{
// 其他代码
application.UseMiddleware<AuthenticationMiddleware>();
}

认证中间件的注册就这么一句代码,实际就是ASPNETCORE请求管道添加认证中间件,最后通过Build初始化到这个请求管道,后续所有的请求都会通过这个认证中间件的invoke方法处理,然后传递下一个中间件,关于中间件的原理也可以看我上一篇帖子。认证系统的配置我们已经准备完成,下面我们看看系统登录。
登录

   [HttpPost]
public virtual IActionResult Login(LoginModel model, string returnUrl, bool captchaValid)
{ // 其他代码
if (ModelState.IsValid)
{
var loginResult = _userService.ValidateUser(model.Username, model.Password);
switch (loginResult)
{
case LoginResults.Successful:
{
var user = _userService.GetUserByUserName(model.Username); _authenticationService.SignIn(user, model.RememberMe); return Redirect(returnUrl);
}
}
} return View(model);
}

以上登录代码片段比较简单,主要完成两个动作,1.收集用户输入的用户名&密码等信息,然后通过我们系统的存储介质,校验用户名&密码的合法性。2.登录到我们的认证系统,实现我们核心登录逻辑是SignIn方法里面。下面我们继续看看SignIn方法的具体实现。

 public virtual async void SignIn(User user, bool isPersistent)
{
// 其他代码
// 创建身份信息集合
var claims = new List<Claim>(); if (!string.IsNullOrEmpty(user.Username))
claims.Add(new Claim(ClaimTypes.Name, user.Username, ClaimValueTypes.String, AuthenticationDefaults.ClaimsIssuer)); if (!string.IsNullOrEmpty(user.Email))
claims.Add(new Claim(ClaimTypes.Email, user.Email, ClaimValueTypes.Email, AuthenticationDefaults.ClaimsIssuer)); var userIdentity = new ClaimsIdentity(claims, AuthenticationDefaults.AuthenticationScheme);
var userPrincipal = new ClaimsPrincipal(userIdentity);
// 辅助信息
var authenticationProperties = new AuthenticationProperties
{
IsPersistent = isPersistent,
IssuedUtc = DateTime.UtcNow
};
// 创建cookie ticket,以备写入response输出到客户端
await _httpContextAccessor.HttpContext.SignInAsync(AuthenticationDefaults.AuthenticationScheme, userPrincipal, authenticationProperties);
}

以上代码片段就完成了我们认证系统的登录。大致逻辑是构建身份声明信息,调用HttpContext的SignInAsync方法创建ticket,在endrequest阶段创建cookie写入response。以上就是我们基于ASPNETCORE平台开发web应用对于认证的真实应用。接下来我们重点看看平台的内部实现。
Cookies认证内部实现
我们还是从服务注册开始吧,毕竟它是完成认证系统的基石。我们把视线转移到上面的AddAuthentication方法,注册服务,我们看看它到底为我们的认证系统注册了哪些基础服务,看NETCORE源代码。

 public static AuthenticationBuilder AddAuthentication(this IServiceCollection services)
{
// 其他代码
services.AddAuthenticationCore();
services.AddDataProtection();
services.AddWebEncoders();
services.TryAddSingleton<ISystemClock, SystemClock>();
return new AuthenticationBuilder(services);
}

从以上代码片段了解到,我们的认证服务注册是在平台AddAuthenticationCore方法里面完成的。我们一起看看AddAuthenticationCore方法的实现。

 public static IServiceCollection AddAuthenticationCore(this IServiceCollection services)
{
services.TryAddScoped<IAuthenticationService, AuthenticationService>();
services.TryAddSingleton<IClaimsTransformation, NoopClaimsTransformation>(); // Can be replaced with scoped ones that use DbContext
services.TryAddScoped<IAuthenticationHandlerProvider, AuthenticationHandlerProvider>();
services.TryAddSingleton<IAuthenticationSchemeProvider, AuthenticationSchemeProvider>();
return services;
}

AddAuthenticationCore方法里面主要注册了我们NETCORE认证系统的三个基础对象,你可以把它们理解为黑帮的一个老大两个堂主,由它们吩咐下面的小弟完成任务,言归正传这三个对象也是完成我们NETCORE平台认证的三剑客,通过Provider模式实现,下面我们一个个来介绍,我们先看看IAuthenticationService接口的定义。

 public interface IAuthenticationService
{
Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme); Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties); Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties); Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties); Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties);
}

IAuthenticationService接口定义了5个方法成员,它本身不实现任何认证逻辑,只是为IAuthenticationSchemeProvider 和 IAuthenticationHandlerProvider这两个Provider实现了封装,提供认证服务的统一接口。下面我大概解释一下这个5个方法在认证服务中的作用。
1.SignInAsync 登录操作,如果登录成功,生成加密ticket,用来标识用户的身份。
2.SignOutAsync 退出登录,清除Coookie等。
3.AuthenticateAsync 解密cookie,获取ticket并验证,最后返回一个 AuthenticateResult 对象,表示用户的身份。
4.ChallengeAsync 未认证,返回 401 状态码。
5.ForbidAsync 权限不足,返回 403 状态码。
下面我们一起看看它的唯一默认实现类AuthenticationService。

 public class AuthenticationService : IAuthenticationService
{ // 其他成员
public AuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform); public IAuthenticationSchemeProvider Schemes { get; } public IAuthenticationHandlerProvider Handlers { get; } public IClaimsTransformation Transform { get; } public virtual async Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme); public virtual async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
{
if (scheme == null)
{
var defaultChallengeScheme = await Schemes.GetDefaultChallengeSchemeAsync();
scheme = defaultChallengeScheme?.Name;
if (scheme == null)
{
throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultChallengeScheme found.");
}
} var handler = await Handlers.GetHandlerAsync(context, scheme);
if (handler == null)
{
throw await CreateMissingHandlerException(scheme);
} await handler.ChallengeAsync(properties);
} public virtual async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties); public virtual async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties); public virtual async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties);
}

代码比较多,我删掉了大部分,其实现逻辑都差不多。我们以ChallengeAsync方法为例,先获取相应的scheme,然后获取对应的Handler,最后执行Handler的同名方法。也就说明,真正的认证逻辑是在Handler里面完成的。从AuthenticationService的定义了解到,AuthenticationService的创建是基于Handlers和schemes创建的,下面我们看看认证的第二个基础对象IAuthenticationSchemeProvider。

 public interface IAuthenticationSchemeProvider
{
Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync(); Task<AuthenticationScheme> GetSchemeAsync(string name); Task<AuthenticationScheme> GetDefaultAuthenticateSchemeAsync(); Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync(); Task<AuthenticationScheme> GetDefaultForbidSchemeAsync(); Task<AuthenticationScheme> GetDefaultSignInSchemeAsync(); Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync(); void AddScheme(AuthenticationScheme scheme); void RemoveScheme(string name); Task<IEnumerable<AuthenticationScheme>> GetRequestHandlerSchemesAsync();
}

scheme其实际就是提供认证方案标识,我们知道,NETCORE的认证系统所支持的认证方案非常丰富,比如openid、bearer、cookie等等。下面我们一起看看它的默认实现AuthenticationSchemeProvider对象。

 public class AuthenticationSchemeProvider : IAuthenticationSchemeProvider
{
public AuthenticationSchemeProvider(IOptions<AuthenticationOptions> options)
: this(options, new Dictionary<string, AuthenticationScheme>(StringComparer.Ordinal))
{
} protected AuthenticationSchemeProvider(IOptions<AuthenticationOptions> options, IDictionary<string, AuthenticationScheme> schemes)
{
_options = options.Value; _schemes = schemes ?? throw new ArgumentNullException(nameof(schemes));
_requestHandlers = new List<AuthenticationScheme>(); foreach (var builder in _options.Schemes)
{
var scheme = builder.Build();
AddScheme(scheme);
}
} private readonly AuthenticationOptions _options;
private readonly object _lock = new object();
private readonly IDictionary<string, AuthenticationScheme> _schemes;
private readonly List<AuthenticationScheme> _requestHandlers;
private IEnumerable<AuthenticationScheme> _schemesCopy = Array.Empty<AuthenticationScheme>();
private IEnumerable<AuthenticationScheme> _requestHandlersCopy = Array.Empty<AuthenticationScheme>(); private Task<AuthenticationScheme> GetDefaultSchemeAsync()
=> _options.DefaultScheme != null
? GetSchemeAsync(_options.DefaultScheme)
: Task.FromResult<AuthenticationScheme>(null); public virtual Task<AuthenticationScheme> GetDefaultAuthenticateSchemeAsync()
=> _options.DefaultAuthenticateScheme != null
? GetSchemeAsync(_options.DefaultAuthenticateScheme)
: GetDefaultSchemeAsync(); public virtual Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync()
=> _options.DefaultChallengeScheme != null
? GetSchemeAsync(_options.DefaultChallengeScheme)
: GetDefaultSchemeAsync(); public virtual Task<AuthenticationScheme> GetDefaultForbidSchemeAsync()
=> _options.DefaultForbidScheme != null
? GetSchemeAsync(_options.DefaultForbidScheme)
: GetDefaultChallengeSchemeAsync(); public virtual Task<AuthenticationScheme> GetDefaultSignInSchemeAsync()
=> _options.DefaultSignInScheme != null
? GetSchemeAsync(_options.DefaultSignInScheme)
: GetDefaultSchemeAsync(); public virtual Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync()
=> _options.DefaultSignOutScheme != null
? GetSchemeAsync(_options.DefaultSignOutScheme)
: GetDefaultSignInSchemeAsync(); public virtual Task<AuthenticationScheme> GetSchemeAsync(string name)
=> Task.FromResult(_schemes.ContainsKey(name) ? _schemes[name] : null); public virtual Task<IEnumerable<AuthenticationScheme>> GetRequestHandlerSchemesAsync()
=> Task.FromResult(_requestHandlersCopy); public virtual void AddScheme(AuthenticationScheme scheme)
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
lock (_lock)
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
if (typeof(IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType))
{
_requestHandlers.Add(scheme);
_requestHandlersCopy = _requestHandlers.ToArray();
}
_schemes[scheme.Name] = scheme;
_schemesCopy = _schemes.Values.ToArray();
}
} public virtual void RemoveScheme(string name); public virtual Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync()
=> Task.FromResult(_schemesCopy);
}

从AuthenticationSchemeProvider的默认实现来看,它主要是提供scheme管理。从AuthenticationSchemeProvider构造器的定义来看,它的初始化是由我们注册服务时所提供的options配置对象提供,其最终初始化体现在AddScheme方法上,也就是对所有注册的scheme添加集合,所有scheme最终体现为一个AuthenticationScheme对象,下面我们看看它的定义。

 public class AuthenticationScheme
{
public AuthenticationScheme(string name, string displayName, Type handlerType)
{
// 其他代码
if (!typeof(IAuthenticationHandler).IsAssignableFrom(handlerType))
{
throw new ArgumentException("handlerType must implement
IAuthenticationHandler.");
} Name = name;
HandlerType = handlerType;
DisplayName = displayName;
} public string Name { get; } public string DisplayName { get; } public Type HandlerType { get; }
}

每一个scheme里面都包含了对应的Handler,同时派生自IAuthenticationHandler。这个handler就是后续真正处理我们的认证实现。下面我们一起看看认证基石的第三个对象IAuthenticationHandlerProvider的定义。

 public interface IAuthenticationHandlerProvider
{
Task<IAuthenticationHandler> GetHandlerAsync(HttpContext context, string authenticationScheme);
}

这个接口的定义很简单,就一个成员,GetHandlerAsync方法,顾名思义就是获取authenticationScheme对应的Handler,我们看看IAuthenticationHandlerProvider的默认实现。

 public class AuthenticationHandlerProvider : IAuthenticationHandlerProvider
{
public AuthenticationHandlerProvider(IAuthenticationSchemeProvider schemes)
{
Schemes = schemes;
} public IAuthenticationSchemeProvider Schemes { get; } private Dictionary<string, IAuthenticationHandler> _handlerMap = new Dictionary<string, IAuthenticationHandler>(StringComparer.Ordinal); public async Task<IAuthenticationHandler> GetHandlerAsync(HttpContext context, string authenticationScheme)
{
if (_handlerMap.ContainsKey(authenticationScheme))
{
return _handlerMap[authenticationScheme];
} var scheme = await Schemes.GetSchemeAsync(authenticationScheme);
if (scheme == null)
{
return null;
}
var handler = (context.RequestServices.GetService(scheme.HandlerType) ??
ActivatorUtilities.CreateInstance(context.RequestServices, scheme.HandlerType))
as IAuthenticationHandler;
if (handler != null)
{
await handler.InitializeAsync(scheme, context);
_handlerMap[authenticationScheme] = handler;
}
return handler;
}
}

GetHandlerAsync方法的实现逻辑也比较简单,首先通过_handlerMap字典根据scheme名称获取,一般首次获取,都是null。然后通过schemeprovide获取对应的scheme,通过上面分析我们知道,scheme体现为一个AuthenticationScheme对象,里面包含了handlertype。最后创建这个handler,创建handler有两种情况,第一种从DI容器获取,第二种情况反射创建,最终返回的是有如下定义的IAuthenticationHandler接口。

 public interface IAuthenticationHandler
{
Task InitializeAsync(AuthenticationScheme scheme, HttpContext context); Task<AuthenticateResult> AuthenticateAsync(); Task ChallengeAsync(AuthenticationProperties properties); Task ForbidAsync(AuthenticationProperties properties);
}

该接口就是实打实干实事的,我们的认证逻辑就是通过该handler实现的。AuthenticateAsync方法就是我们的认证入口,其返回类型是一个AuthenticateResult类型,也就是我们的认证结果,接下来我们看看它的定义。

 public class AuthenticateResult
{
protected AuthenticateResult() { } public bool Succeeded => Ticket != null; public AuthenticationTicket Ticket { get; protected set; } public ClaimsPrincipal Principal => Ticket?.Principal; public AuthenticationProperties Properties { get; protected set; } public Exception Failure { get; protected set; } public bool None { get; protected set; } public static AuthenticateResult Success(AuthenticationTicket ticket)
{
if (ticket == null)
{
throw new ArgumentNullException(nameof(ticket));
}
return new AuthenticateResult() { Ticket = ticket, Properties = ticket.Properties };
} public static AuthenticateResult NoResult()
{
return new AuthenticateResult() { None = true };
} public static AuthenticateResult Fail(Exception failure)
{
return new AuthenticateResult() { Failure = failure };
} public static AuthenticateResult Fail(Exception failure, AuthenticationProperties properties)
{
return new AuthenticateResult() { Failure = failure, Properties = properties };
} public static AuthenticateResult Fail(string failureMessage)
=> Fail(new Exception(failureMessage)); public static AuthenticateResult Fail(string failureMessage, AuthenticationProperties properties)
=> Fail(new Exception(failureMessage), properties);
}

如上代码,AuthenticateResult对象的定义逻辑很简单,就是包装认证结果信息,比如AuthenticationTicket,它主要定义了我们的基本认证信息,我们可以把它理解为一张认证后的票据信息。AuthenticationProperties类型它主要定义了我们认证相关的辅助信息,其中包括过期、重定向、持久等等信息。关于这两个类型的定义我就不贴代码了,其实现比较简单。兜兜转转终于到了我们的cooke认证实现类CookieAuthenticationHandler对象,下面我们一起看看它的定义。

 public class CookieAuthenticationHandler : SignInAuthenticationHandler<CookieAuthenticationOptions>
{
// 其他代码
public CookieAuthenticationHandler(IOptionsMonitor<CookieAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{ } protected override async Task<AuthenticateResult> HandleAuthenticateAsync(); protected virtual async Task FinishResponseAsync(); protected async override Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties); protected async override Task HandleSignOutAsync(AuthenticationProperties properties); protected override async Task HandleForbiddenAsync(AuthenticationProperties properties); protected override async Task HandleChallengeAsync(AuthenticationProperties properties);
}

我们暂且先不讨论CookieAuthenticationHandler认证实现逻辑,因为整个认证结构,有涉及多个Handler对象,我们还是一步一步按照这个层次结构来介绍吧,至少大家不会觉得突兀。从CookieAuthenticationHandler的定义来看,它并未直接实现IAuthenticationHandler,还是实现了有着如下定义的SignInAuthenticationHandler接口对象。

 public abstract class SignInAuthenticationHandler<TOptions> : SignOutAuthenticationHandler<TOptions>, IAuthenticationSignInHandler
where TOptions : AuthenticationSchemeOptions, new()
{
public SignInAuthenticationHandler(IOptionsMonitor<TOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{ } public virtual Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
{
var target = ResolveTarget(Options.ForwardSignIn);
return (target != null)
? Context.SignInAsync(target, user, properties)
: HandleSignInAsync(user, properties ?? new AuthenticationProperties());
} protected abstract Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties);
}

从该对象的定义来看,它就是负责处理登录相关处理的。其中还有SignOutAuthenticationHandler,处理逻辑类似,负责登出操作,可能有些朋友会觉得有点奇怪,为什么登入登出会单独定义成相关接口,个人理解,其一站在业务的角度,登入、登出和认证还是有一定的独立性,并非所有业务场景必须要先登录才能实现认证,而且认证更多关注的是过程,其二以适应更多认证方式,把登入登出抽象出来,使其扩展更方便。它们派生自抽象类AuthenticationHandler<TOptions>,下面我们看看它的定义。

 public abstract class AuthenticationHandler<TOptions> : IAuthenticationHandler where TOptions : AuthenticationSchemeOptions, new()
{
// 其他代码
protected AuthenticationHandler(IOptionsMonitor<TOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
{
Logger = logger.CreateLogger(this.GetType().FullName);
UrlEncoder = encoder;
Clock = clock;
OptionsMonitor = options;
} public async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
if (scheme == null)
{
throw new ArgumentNullException(nameof(scheme));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
} Scheme = scheme;
Context = context; Options = OptionsMonitor.Get(Scheme.Name); await InitializeEventsAsync();
await InitializeHandlerAsync();
} protected virtual async Task InitializeEventsAsync()
{
Events = Options.Events;
if (Options.EventsType != null)
{
Events = Context.RequestServices.GetRequiredService(Options.EventsType);
}
Events = Events ?? await CreateEventsAsync();
} protected virtual Task<object> CreateEventsAsync() => Task.FromResult(new object()); protected virtual Task InitializeHandlerAsync() => Task.CompletedTask; protected string BuildRedirectUri(string targetPath)
=> Request.Scheme + "://" + Request.Host + OriginalPathBase + targetPath; protected virtual string ResolveTarget(string scheme)
{
var target = scheme ?? Options.ForwardDefaultSelector?.Invoke(Context) ?? Options.ForwardDefault; // Prevent self targetting
return string.Equals(target, Scheme.Name, StringComparison.Ordinal)
? null
: target;
} public async Task<AuthenticateResult> AuthenticateAsync()
{
var target = ResolveTarget(Options.ForwardAuthenticate);
if (target != null)
{
return await Context.AuthenticateAsync(target);
} var result = await HandleAuthenticateOnceAsync();
if (result?.Failure == null)
{
var ticket = result?.Ticket;
if (ticket?.Principal != null)
{
Logger.AuthenticationSchemeAuthenticated(Scheme.Name);
}
else
{
Logger.AuthenticationSchemeNotAuthenticated(Scheme.Name);
}
}
else
{
Logger.AuthenticationSchemeNotAuthenticatedWithFailure(Scheme.Name, result.Failure.Message);
}
return result;
} protected Task<AuthenticateResult> HandleAuthenticateOnceAsync()
{
if (_authenticateTask == null)
{
_authenticateTask = HandleAuthenticateAsync();
} return _authenticateTask;
} protected async Task<AuthenticateResult> HandleAuthenticateOnceSafeAsync()
{
try
{
return await HandleAuthenticateOnceAsync();
}
catch (Exception ex)
{
return AuthenticateResult.Fail(ex);
}
} protected abstract Task<AuthenticateResult> HandleAuthenticateAsync(); protected virtual Task HandleForbiddenAsync(AuthenticationProperties properties)
{
Response.StatusCode = ;
return Task.CompletedTask;
} protected virtual Task HandleChallengeAsync(AuthenticationProperties properties)
{
Response.StatusCode = ;
return Task.CompletedTask;
} public async Task ChallengeAsync(AuthenticationProperties properties)
{
var target = ResolveTarget(Options.ForwardChallenge);
if (target != null)
{
await Context.ChallengeAsync(target, properties);
return;
} properties = properties ?? new AuthenticationProperties();
await HandleChallengeAsync(properties);
Logger.AuthenticationSchemeChallenged(Scheme.Name);
} public async Task ForbidAsync(AuthenticationProperties properties)
{
var target = ResolveTarget(Options.ForwardForbid);
if (target != null)
{
await Context.ForbidAsync(target, properties);
return;
} properties = properties ?? new AuthenticationProperties();
await HandleForbiddenAsync(properties);
Logger.AuthenticationSchemeForbidden(Scheme.Name);
}
}

该抽象类直接实现了我们上面提到的认证接口IAuthenticationHandler,是NETCORE所有认证类的基类,并且提供相关默认实现。抽象方法HandleAuthenticateAsync就是我们认证处理的入口,也是认证的核心实现,由具体的认证实现类实现。该基类的其他方法,逻辑都比较简单,或者只提供默认实现就不再赘述,接下来我们围绕上面提到的cookie认证的核心实现类CookieAuthenticationHandler介绍其具体认证实现,在介绍其具体实现之前,我们来看看它是如何被创建的或者说被注入到我们的DI容器的,其实是通过Startup的ConfigureServices方法注册进来的,看代码。

 public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<CookieAuthenticationOptions> configureOptions)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());
builder.Services.AddOptions<CookieAuthenticationOptions>(authenticationScheme).Validate(o => o.Cookie.Expiration == null, "Cookie.Expiration is ignored, use ExpireTimeSpan instead.");
return builder.AddScheme<CookieAuthenticationOptions, CookieAuthenticationHandler>(authenticationScheme, displayName, configureOptions);
}

通过CookieExtensions的扩展方法AddCookie方法注入进来的,有疑惑的朋友可以看看我在开始介绍NETCORE认证的开始部分就贴出了这段代码。接下来我们继续看认证核心部分。

 public class CookieAuthenticationHandler : SignInAuthenticationHandler<CookieAuthenticationOptions>
{
// 其他成员
public CookieAuthenticationHandler(IOptionsMonitor<CookieAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{ } protected new CookieAuthenticationEvents Events
{
get { return (CookieAuthenticationEvents)base.Events; }
set { base.Events = value; }
}
// 初始化handler,设置响应cookie回调
protected override Task InitializeHandlerAsync()
{
// Cookies needs to finish the response
Context.Response.OnStarting(FinishResponseAsync);
return Task.CompletedTask;
}
// cookie认证各个处理阶段,默认注册的事件
protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new CookieAuthenticationEvents());
// 获取ticket票据
private Task<AuthenticateResult> EnsureCookieTicket();
// 刷新票据
private void CheckForRefresh(AuthenticationTicket ticket); private void RequestRefresh(AuthenticationTicket ticket, ClaimsPrincipal replacedPrincipal = null);
// clone票据
private AuthenticationTicket CloneTicket(AuthenticationTicket ticket, ClaimsPrincipal replacedPrincipal); private async Task<AuthenticateResult> ReadCookieTicket();
// cookie认证
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
// 获取票据
var result = await EnsureCookieTicket();
if (!result.Succeeded)
{
return result;
}
// 用户信息验证,默认没有任何逻辑实现
var context = new CookieValidatePrincipalContext(Context, Scheme, Options, result.Ticket);
await Events.ValidatePrincipal(context); if (context.Principal == null)
{
return AuthenticateResult.Fail("No principal.");
}
// 更新ticket票据,一般在之前会更新用户信息
if (context.ShouldRenew)
{
RequestRefresh(result.Ticket, context.Principal);
}
// 认证成功,包装result返回
return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
}
// 写入response
protected virtual async Task FinishResponseAsync();
// 登录,
protected async override Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
// 获取配置信息
properties = properties ?? new AuthenticationProperties(); _signInCalled = true; // 初始化,比如sessionkey
await EnsureCookieTicket();
var cookieOptions = BuildCookieOptions();
// 创建cookiecontext,以备写入response
var signInContext = new CookieSigningInContext(
Context,
Scheme,
Options,
user,
properties,
cookieOptions);
// 设置认证辅助信息,比如过期时间等等。
DateTimeOffset issuedUtc;
if (signInContext.Properties.IssuedUtc.HasValue)
{
issuedUtc = signInContext.Properties.IssuedUtc.Value;
}
else
{
issuedUtc = Clock.UtcNow;
signInContext.Properties.IssuedUtc = issuedUtc;
} if (!signInContext.Properties.ExpiresUtc.HasValue)
{
signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
}
// 执行signin阶段处理事件,如果有重写,执行重写逻辑
await Events.SigningIn(signInContext);
// 是否持久化
if (signInContext.Properties.IsPersistent)
{
var expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan);
signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime();
}
// 创建认证票据ticket
var ticket = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.Scheme.Name);
// 基于session逻辑,实现复杂的cookie信息缓存到服务端
if (Options.SessionStore != null)
{
if (_sessionKey != null)
{
await Options.SessionStore.RemoveAsync(_sessionKey);
}
_sessionKey = await Options.SessionStore.StoreAsync(ticket);
var principal = new ClaimsPrincipal(
new ClaimsIdentity(
new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
Options.ClaimsIssuer));
ticket = new AuthenticationTicket(principal, null, Scheme.Name);
}
// 加密票据
var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());
// 设置response响应头
Options.CookieManager.AppendResponseCookie(
Context,
Options.Cookie.Name,
cookieValue,
signInContext.CookieOptions); var signedInContext = new CookieSignedInContext(
Context,
Scheme,
signInContext.Principal,
signInContext.Properties,
Options);
// 登录后的事件处理
await Events.SignedIn(signedInContext); var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath;
await ApplyHeaders(shouldRedirect, signedInContext.Properties); Logger.AuthenticationSchemeSignedIn(Scheme.Name);
}
// 登出
protected async override Task HandleSignOutAsync(AuthenticationProperties properties); private async Task ApplyHeaders(bool shouldRedirectToReturnUrl, AuthenticationProperties properties);
// 权限不足
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
{
var returnUrl = properties.RedirectUri;
if (string.IsNullOrEmpty(returnUrl))
{
returnUrl = OriginalPathBase + OriginalPath + Request.QueryString;
}
var accessDeniedUri = Options.AccessDeniedPath + QueryString.Create(Options.ReturnUrlParameter, returnUrl);
var redirectContext = new RedirectContext<CookieAuthenticationOptions>(Context, Scheme, Options, properties, BuildRedirectUri(accessDeniedUri));
await Events.RedirectToAccessDenied(redirectContext);
}
// 未认证用户,访问保护的资源
protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
{
// 通过配置信息获取重定向url
var redirectUri = properties.RedirectUri;
if (string.IsNullOrEmpty(redirectUri))
{
redirectUri = OriginalPathBase + OriginalPath + Request.QueryString;
} var loginUri = Options.LoginPath + QueryString.Create(Options.ReturnUrlParameter, redirectUri);
var redirectContext = new RedirectContext<CookieAuthenticationOptions>(Context, Scheme, Options, properties, BuildRedirectUri(loginUri));
// 重定向到登录页面
await Events.RedirectToLogin(redirectContext);
}
}

以上就是cookie认证的核心实现,代码注释比较详细,接下来我大致描述一下cookie认证的处理逻辑,其实跟传统的Forms或者Katana的cookie认证思路差不多。
1.首先获取请求cookie,解密并创建ticket票据。
2.如果配置了sessionstore方案,通过sessionkey获取用户完整的声明信息。
3.校验过期,如果未过期。
4.更新cookie,条件为过期时间范围已过半。
5.校验用户信息,主要是针对cookie未失效,用户声明信息发生变更。
6.返回AuthenticateResult认证结果对象。
以上6点就是我个人针对NETCOREcookie认证的理解。接下来我们一起看看,认证中间件是如何关联它们,实现我们的系统认证。
认证中间件
下面我们看看认证中间件的定义。

 public class AuthenticationMiddleware
{
#region Fields private readonly RequestDelegate _next; #endregion #region Ctor public AuthenticationMiddleware(IAuthenticationSchemeProvider schemes, RequestDelegate next)
{
Schemes = schemes ?? throw new ArgumentNullException(nameof(schemes));
_next = next ?? throw new ArgumentNullException(nameof(next));
} #endregion #region Properties public IAuthenticationSchemeProvider Schemes { get; set; } #endregion #region Methods public async Task Invoke(HttpContext context)
{
context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
{
OriginalPath = context.Request.Path,
OriginalPathBase = context.Request.PathBase
}); var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
{
try
{
if (await handlers.GetHandlerAsync(context, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync())
return;
}
catch
{
}
} var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
if (defaultAuthenticate != null)
{
var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
if (result?.Principal != null)
{
context.User = result.Principal;
}
} await _next(context);
} #endregion
}

如上认证中间件就是这么简单,关于中间件的原理可以参看我上一篇帖子。
1.首先从DI里面获取IAuthenticationHandlerProvider的默认实现类AuthenticationHandlerProvider。
2.从schemes里面获取所有实现IAuthenticationRequestHandler接口的handler,没有什么特别的,就是多了一个请求方法,后续我会介绍,暂时我们把它理解为三方认证的实现handler。
3.如果有注册该handler实例,将调用认证逻辑。
4.如果没有注册requesthandler实例,获取默认scheme。
5.从指定的scheme里面获取具体认证handler实现认证。
6.如果认证成功,返回result,并赋值httpcontext.user属性,完成认证。

最后总结

本来打算把NETCORE的授权也一并讲完,实在想睡觉了,今天就到这吧。下面我来做个简单的总结吧,关于NET平台甚至NETCORE基于cookie认证的实现思路大致是一样的,只是细节上面的区别,当然我理解的可能有些错误。我们学习微软web平台的认证授权,其一是更好的掌握这个平台,其二是学习他的设计思路,当我们自己在实际开发中碰到安全相关的问题,如何去合理设计,更好的保证系统的安全性等等。

ASPNET-ASPNETCORE 认证的更多相关文章

  1. aspnetcore 认证相关类简要说明二

    能过<aspnetcore 认证相关类简要说明一>我们已经了解如何将AuthenticationOptions注入到我们依赖注入系统.接下来,我们将了解一下IAuthenticationS ...

  2. AspNet Core 认证

    一 Cookie认证 1  services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCooki ...

  3. aspnetcore 认证相关类简要说明三

    今天我们再来了解一个很重要的接口IAuthenticationService的实现类AuthenticationService: public class AuthenticationService ...

  4. aspnetcore 认证相关类简要说明一

    首先我想要简要说明是AuthenticationScheme类,每次看到Scheme这个单词我就感觉它是一个很高大上的单词,其实简单翻译过来就是认证方案的意思.既然一种方案,那我们就要知道这个方案的名 ...

  5. IdentityServer4授权和认证

    IdentityServer4 简称ids4 oidc了解:http://www.jessetalk.cn/2018/04/04/oidc-asp-net-core/ 是一个去中心化的网上身份认证系统 ...

  6. asp.net core系列 52 Identity 其它关注点

    一.登录分析 在使用identity身份验证登录时,在login中调用的方法是: var result = await _signInManager.PasswordSignInAsync(Input ...

  7. 任务38:JWT 设计解析及定制

    任务38:JWT 设计解析及定制 改造jwt token token的值不放在Authorize里面,而是放在header的token里面 asp.net core的源代码 在Security的下面 ...

  8. asp.net core 使用 signalR(二)

    asp.net core 使用 signalR(二) Intro 上次介绍了 asp.net core 中使用 signalR 服务端的开发,这次总结一下web前端如何接入和使用 signalR,本文 ...

  9. ASP.NET Core 2.0升级到3.0的变化和问题

    前言 在.NET Core 2.0发布的时候,博主也趁热使用ASP.NET Core 2.0写了一个独立的博客网站,现如今恰逢.NET Core 3.0发布之际,于是将该网站进行了升级. 下面就记录升 ...

随机推荐

  1. 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树

    [BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...

  2. SAM4E单片机之旅——7、LED闪烁之TC中断

    RTT主要用做一个全局的定时器,而且不太通用.现在尝试使用一个更为通用的定时器进行定时:定时计数器(Timer Counter, TC). TC提供了广泛的功能,主要可以分为对输入的测量,以及波形的输 ...

  3. EasyDarwin实现RTSP播放动态认证的两种方式:Basic/Digest & Token

    问题描述 目前为了能够方便开发者,我们将EasyDarwin中的RTSP认证过程直接忽略过了,如果要开启认证的方式,我们可以在代码中打开: case kRoutingRequest: { // Inv ...

  4. splittability A SequenceFile can be split by Hadoop and distributed across map jobs whereas a GZIP file cannot be.

    splittability CompressedStorage     Skip to end of metadata   Created by Confluence Administrator, l ...

  5. 学习selendroid初衷

    为了解决工作中的一个问题,开始学习selendroid. 工作中,有一些所谓H5应用需要测试,这些应用程序描述如下: 通过微信平台传播,也就是依靠微信的朋友圈传播: 可以通过类似于http://XXX ...

  6. RabbitMQ的介绍与spring整合

    本文主要讲述的是个人参考官网及其他前辈博客,对RabbitMQ的一些理解与spring整个RabbitMQ. 一.RabbitMQ的介绍 1.1.什么是RabbitMQ RabbitMQ是一个由erl ...

  7. Gym - 101147G G - The Galactic Olympics —— 组合数学 - 第二类斯特林数

    题目链接:http://codeforces.com/gym/101147/problem/G G. The Galactic Olympics time limit per test 2.0 s m ...

  8. IPFS 到底是怎么工作的?

    简介 我们知道,一个存储服务,最基本的功能就是存和取.IPFS 中提供了这两种语义,那就是 add 和 get 操作. 在 IPFS 系统中执行 add 操作,就是执行了一次存操作,放在网络的概念里, ...

  9. servlet与jsp理论知识讲解

    servlet是java服务器端编程,是运行在服务器上的.不同于以前的java小程序.                                                         ...

  10. Idea中的插件-列出Java Bean的所有set方法

    插件的git 地址: https://github.com/yoke233/genSets 将插件jar导入idea中,使用方式是对象后加.allset,然后回车.