ASPNET-ASPNETCORE 认证
话题背景
关于认证我的个人理解是,验证信息的合法性。在我们生活当中,比如门禁,你想进入一个有相对安全措施的小区或者大楼,你需要向保安或者门禁系统提供你的身份信息证明,只有确定你是小区业主,才可以进来,我这只是打个比方啊,不要纠结。对于我们计算机的安全领域,认证其实也非常类似,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 认证的更多相关文章
- aspnetcore 认证相关类简要说明二
能过<aspnetcore 认证相关类简要说明一>我们已经了解如何将AuthenticationOptions注入到我们依赖注入系统.接下来,我们将了解一下IAuthenticationS ...
- AspNet Core 认证
一 Cookie认证 1 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCooki ...
- aspnetcore 认证相关类简要说明三
今天我们再来了解一个很重要的接口IAuthenticationService的实现类AuthenticationService: public class AuthenticationService ...
- aspnetcore 认证相关类简要说明一
首先我想要简要说明是AuthenticationScheme类,每次看到Scheme这个单词我就感觉它是一个很高大上的单词,其实简单翻译过来就是认证方案的意思.既然一种方案,那我们就要知道这个方案的名 ...
- IdentityServer4授权和认证
IdentityServer4 简称ids4 oidc了解:http://www.jessetalk.cn/2018/04/04/oidc-asp-net-core/ 是一个去中心化的网上身份认证系统 ...
- asp.net core系列 52 Identity 其它关注点
一.登录分析 在使用identity身份验证登录时,在login中调用的方法是: var result = await _signInManager.PasswordSignInAsync(Input ...
- 任务38:JWT 设计解析及定制
任务38:JWT 设计解析及定制 改造jwt token token的值不放在Authorize里面,而是放在header的token里面 asp.net core的源代码 在Security的下面 ...
- asp.net core 使用 signalR(二)
asp.net core 使用 signalR(二) Intro 上次介绍了 asp.net core 中使用 signalR 服务端的开发,这次总结一下web前端如何接入和使用 signalR,本文 ...
- ASP.NET Core 2.0升级到3.0的变化和问题
前言 在.NET Core 2.0发布的时候,博主也趁热使用ASP.NET Core 2.0写了一个独立的博客网站,现如今恰逢.NET Core 3.0发布之际,于是将该网站进行了升级. 下面就记录升 ...
随机推荐
- 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树
[BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...
- SAM4E单片机之旅——7、LED闪烁之TC中断
RTT主要用做一个全局的定时器,而且不太通用.现在尝试使用一个更为通用的定时器进行定时:定时计数器(Timer Counter, TC). TC提供了广泛的功能,主要可以分为对输入的测量,以及波形的输 ...
- EasyDarwin实现RTSP播放动态认证的两种方式:Basic/Digest & Token
问题描述 目前为了能够方便开发者,我们将EasyDarwin中的RTSP认证过程直接忽略过了,如果要开启认证的方式,我们可以在代码中打开: case kRoutingRequest: { // Inv ...
- 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 ...
- 学习selendroid初衷
为了解决工作中的一个问题,开始学习selendroid. 工作中,有一些所谓H5应用需要测试,这些应用程序描述如下: 通过微信平台传播,也就是依靠微信的朋友圈传播: 可以通过类似于http://XXX ...
- RabbitMQ的介绍与spring整合
本文主要讲述的是个人参考官网及其他前辈博客,对RabbitMQ的一些理解与spring整个RabbitMQ. 一.RabbitMQ的介绍 1.1.什么是RabbitMQ RabbitMQ是一个由erl ...
- 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 ...
- IPFS 到底是怎么工作的?
简介 我们知道,一个存储服务,最基本的功能就是存和取.IPFS 中提供了这两种语义,那就是 add 和 get 操作. 在 IPFS 系统中执行 add 操作,就是执行了一次存操作,放在网络的概念里, ...
- servlet与jsp理论知识讲解
servlet是java服务器端编程,是运行在服务器上的.不同于以前的java小程序. ...
- Idea中的插件-列出Java Bean的所有set方法
插件的git 地址: https://github.com/yoke233/genSets 将插件jar导入idea中,使用方式是对象后加.allset,然后回车.