[翻译] 探究 Asp.net core 中间件 JWT bearer authentication 背后的技术
本文译自: https://andrewlock.net/a-look-behind-the-jwt-bearer-authentication-middleware-in-asp-net-core/
本篇已收录至 asp.net core 随笔系列
这篇文章是 asp.net core authentication 和 authorisation 系列中的一篇. 在第一篇中我们了解了关于 authentication 和 authorisation 的基础概念, 并且在随后的一篇了解 cookie middleware 的一些理论. 现在我们需要看看另一个中间件, 就是 JwtBearerAuthenticationMiddleware
. 并且看看其底层的实现how it is implemented in ASP.NET Core
什么是 Bearer Authentication?
简单来说, 就是展示一个有效的令牌以后,你将会自动通过身份认证环节, 不需要任何其他额外的细节去证明确实是给你的令牌. 这种认证方式经常被用于 OAuth 2.0 认证框架中, 比如你经常会遇到使用第三方的账号登录某个app的过程.在实际的使用中, bearer token一般会被放在 http authorization header 中:
Authorization: Bearer BEARER_TOKEN
有一点很重要需要记住的是, 谁有令牌谁就可以访问被保护的资源, 所以一定要在 SSL/TLS 的协议中使用token,以防止token被拦截盗用等风险.
什么是 JWT?
JSON Web Token. 就是将之前一堆claims用一种web标准给转换成为JSON对象. 并且这个JSON对象是可以被签名加密和解密的. 所以被广泛的使用与当前互联网应用中. 尤其是对于那些实现了 OAuth 2.0 的应用中.
JWT包含三部分:
Header: 一个JSON对象, 用于定义和说明token的类型并且用于签名的算法.
Payload: 一个JSON对象, 用于表述 Claims的主体内容.
Signature: 一个将header和payload加密的字符串, 用于保证令牌没有被修改过.
然后这三部分会分别通过 base64Url 进行编码, 然后用 .
链接起来. 所以使用 JWT 可以允许你通过一种打包的方式发送 Claims, 并且通过签名的方式保证不会被更改. 其最大的优点是在于那些无状态的应用程序中, 通过token验证身份, 而不必依赖于 server 端的 session 来验证身份. (译者按: 当 server 端不依赖 session, 才是分布式 server 的基础.)
此处不会详细说明什么 JWT tokens, 以及 OAuth, 因为它们本身是一个非常大的话题. 在这篇文章中我更有兴趣的是讨论中间件是如何与 Asp.net Core 协作使用的. 如果你对前两者有兴趣, 我建议你去看看 jwt.io 和 auth0.com , 官网上有很多很好的信息和教程. 这里仅仅给出一个模糊的 JWT:
{
"alg": "HS256",
"typ": "JWT"
}
{
"name": "Andrew Lock"
}
可以被编码后放入header中:
Authorisation: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiQW5kcmV3IExvY2sifQ.RJJq5u9ITuNGeQmWEA4S8nnzORCpKJ2FXUthuCuCo0I
JWT bearer authentication in ASP.NET Core
你可以添加 JWT bearer authentication 到你的 asp.net core app中通过nuget pacakge: Microsoft.AspNetCore.Authentication.JwtBearer. 这个package提供了一个中间件允许扩展和使用 JWT bearer tokens. 目前没有一个 built-in 的机制为你生成 tokens. 但是如果你有需要的话,目前有很多项目和解决方案能够提供, 比如 IdentityServer 4. 当然你也可以通过这篇文章来创建自己的 token 中间件.
当你添加了package到项目后, 你需要在 startup.cs 中对中间件进行配置.
JwtBearerMiddleware
当中间件被创建后, 会做一系列的预检查, 并初始化一部分默认属性值, 最重要的就是初始化 ConfigurationManager. 因为它主要是用于获取用于验证,刷新以及缓存JWT的配置信息.比如 issuer 和 signing key.
JwtBearerHandler
正如 cookie authentication 中间件中最主要的逻辑在 handler中, jwtBearerHandler也是非常主要的一环, 它重写了 HandleAuthenticateAsync()方法.
这个方法的主要职责是用于解序列化 JWT, 验证, 以及创建一个 AuthenticateReuslt 带有一个 AuthenticationTicket(如果验证能够通过的话.)