如何将ASP.NET Core WebAPI的JWT Bearer认证和授权机制为?

摘要:[TOC] 为什么是 JWT Bearer ASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 , , , 等, Cookie 认证是一种比较常用本地认证方式,
目录为什么是 JWT Bearer什么是 JWTJWT 的优缺点在 WebAPI 中使用 JWT 认证刷新 Token使用授权简单授权基于固定角色的授权基于策略的授权自定义策略授权基于资源的授权源代码参考 为什么是 JWT Bearer ASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 Cookie, JwtBearer, OAuth, OpenIdConnect 等, Cookie 认证是一种比较常用本地认证方式, 它由浏览器自动保存并在发送请求时自动附加到请求头中, 更适用于 MVC 等纯网页系统的本地认证. OAuth & OpenID Connect 通常用于运程认证, 创建一个统一的认证中心, 来统一配置和处理对于其他资源和服务的用户认证及授权. JwtBearer 认证中, 客户端通常将 JWT(一种Token) 通过 HTTP 的 Authorization header 发送给服务端, 服务端进行验证. 可以方便的用于 WebAPI 框架下的本地认证. 当然, 也可以完全自己实现一个WebAPI下基于Token的本地认证, 比如自定义Token的格式, 自己写颁发和验证Token的代码等. 这样的话通用性并不好, 而且也需要花费更多精力来封装代码以及处理细节. 什么是 JWT JWT (JSON Web Token) 是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。 作为一个开放的标准(RFC 7519),定义了一种简洁的、自包含的方法,从而使通信双方实现以JSON对象的形式安全的传递信息。 JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。 头信息指定了该JWT使用的签名算法: header = {"alg": "HS256", "typ": "JWT"} 消息体包含了JWT的意图: payload = {"sub": "1234567890", "name": "John Doe", "iat": 1516239022} 未签名的令牌由base64url编码的头信息和消息体拼接而成(使用"."分隔),签名则通过私有的key计算而成: key = "secretkey" unsignedToken = encodeBase64(header) + '.' + encodeBase64(payload) signature = HMAC-SHA256(key, unsignedToken) 最后在尾部拼接上base64url编码的签名(同样使用"."分隔)就是JWT了: token = encodeBase64(header) + '.' + encodeBase64(payload) + '.' + encodeBase64(signature) JWT常常被用作保护服务端的资源,客户端通常将JWT通过HTTP的Authorization header发送给服务端,服务端使用自己保存的key计算、验证签名以判断该JWT是否可信。 Authorization: Bearer <token> JWT 的优缺点 相比于传统的 cookie-session 认证机制,优点有: 更适用分布式和水平扩展 在cookie-session方案中,cookie内仅包含一个session标识符,而诸如用户信息、授权列表等都保存在服务端的session中。如果把session中的认证信息都保存在JWT中,在服务端就没有session存在的必要了。当服务端水平扩展的时候,就不用处理session复制(session replication)/ session黏连(sticky session)或是引入外部session存储了。 适用于多客户端(特别是移动端)的前后端解决方案 移动端使用的往往不是网页技术,使用Cookie验证并不是一个好主意,因为你得和Cookie容器打交道,而使用Bearer验证则简单的多。 无状态化 JWT 是无状态化的,更适用于 RESTful 风格的接口验证。 它的缺点也很明显: 更多的空间占用 JWT 由于Payload里面包含了附件信息,占用空间往往比SESSION ID大,在HTTP传输中会造成性能影响。所以在设计时候需要注意不要在JWT中存储太多的claim,以避免发生巨大的,过度膨胀的请求。 无法作废已颁布的令牌 所有的认证信息都在JWT中,由于在服务端没有状态,即使你知道了某个JWT被盗取了,你也没有办法将其作废。
阅读全文