Sometimes people don't need advice, they just need someone to listen and care.
Toggle navigation
Home
Archives
Tags
About
使用OAuth2和JWT鉴权
微服务
授权
安全
2018-03-12 08:30:01
589
1
0
william
微服务
授权
安全
## 背景 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇,很多互联网行业巨头、开源社区等都开始了微服务的讨论和实践。尽管微服务带来了很多好处,但同时也引入了一些新的问题。例如: - 单体应用拆分为分布式系统后,进程间的通讯机制和故障处理措施变的更加复杂。 - 系统微服务化后,一个看似简单的功能,内部可能需要调用多个服务并操作多个数据库实现,服务调用的分布式事务问题变的非常突出。 - 微服务之间权限如何校验 那么,“如何才能在微服务体系中保证安全?” 下面我们来了解下OAuth 2和JWT(JSON Web Tokens)技术作为解决方案。 ## OAuth2 ### 名词解释 1. Third-party application:第三方应用程序,本文中又称"客户端"(client),即上一节例子中的"云冲印"。 2. HTTP service:HTTP服务提供商,本文中简称"服务提供商",即上一节例子中的Google。 3. Resource Owner:资源所有者,本文中又称"用户"(user)。 4. User Agent:用户代理,本文中就是指浏览器。 5. Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。 6. Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。 ### 授权流程 OAuth 2.0的运行流程如下图,摘自RFC 6749。  OAuth运行流程 >(A)用户打开客户端以后,客户端要求用户给予授权。 (B)用户同意给予客户端授权。 (C)客户端使用上一步获得的授权,向认证服务器申请令牌。 (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。 (E)客户端使用令牌,向资源服务器申请获取资源。 (F)资源服务器确认令牌无误,同意向客户端开放资源。 不难看出来,上面六个步骤之中,B是关键,即用户怎样才能给于客户端授权。有了这个授权以后,客户端就可以获取令牌,进而凭令牌获取资源。 ### 示例流程 当William试图登录某App,某App将他重定向到微信的授权服务器,当William登录成功,并且许可自己的Email和个人信息被某App获取。这两个资源被定义成一个Scope(权限范围),一旦准许,某App的开发者就可以申请访问权限范围中定义的这两个资源。 William允许了权限请求,再次通过重定向返回某App,重定向返回时携带了一个Access Token(访问令牌),接下来某App就可以通过这个Access Token从微信直接获取相关的授权资源(也就是Email和个人信息),而无需重新做William相关的鉴权。 ## JWT(JSON Web Tokens) 简单总结来说,JWT是一个定义一种紧凑的,自包含的并且提供防篡改机制的传递数据的方式的标准协议。 我们先来看一个简单的示例: ```json eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9.hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk ``` 就是这么一堆看起来像是乱码一样的字符串。JWT由3部分构成:header.payload.signature,每个部分由“.”来分割开来。 ### Header header是一个有效的JSON,其中通常包含了两部分:token类型和加密算法。 ```json { "alg": "HS256", "typ": "JWT" } ``` 对这个JSON采用base64编码后就是第1部分eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。 ### Payload 这一部分代表真正想要传递的数据,包含一组Claims,其中JWT预定义了一些Claim(2. Token 元数据 这一节就用到一些JWT预定义的一些Cliam)后面会介绍。关于什么是Claim,可以参考文章末尾给的参考链接。 ```json { "sub": "1234567890", "name": "linianhui" } ``` 对这个JSON采用base64编码后就是第2部分eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9。 ### Signature 这一部分是可选的,由于前面Header和Payload部分是明文的信息,所以这一部分的意义在于保障信息不被篡改用的,生成这部分的方式如下: ```json HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) ``` 使用header中指定的签名算法对“header.payload”部分进行签名,得到的第3部分hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk。然后组合成一个完整的JWT字符串,而接收方使用同样的签名算法来生成签名,来判断header和payload部分有没有被篡改锅,因为签名的密钥是只有通信双方知道的,所以可以保证这部分信息不被第三方所篡改。 ### JWT的一些Claims JWT规范中预先定义了一些Cliam,但并不是必选的,常用的有: > - iss(Issuer签发者)。 - sub(subject签发给的受众,在Issuer范围内是唯一的)。 - aud(Audience接收方)。 - exp(Expiration Time过期时间)。 - iat(Issued At签发时间)等等。 更完整的一些Claim列表参见:https://www.iana.org/assignments/jwt/jwt.xhtml 如果上面这些仍无法满足自己的需要,则可以自定义一些来使用。 ## OAuth2 & JWT 使用JWT可以简单的传输Token,用RSA签名保证Token很难被伪造。Access Token字符串中包含用户信息和权限范围,我们所需的全部信息都有了,所以不需要维护Token存储,资源服务器也不必要求Token检查。 比如我们把权限信息打包进JWT,最终生成OAuth2授权的Token。资源服务器在拿到这个Token时就可以知道这个Token包含了什么权限,决定可以访问用户的哪些资源。 ```json { "scope":"userinfo+headportrait", "exp":123456789, } ``` ## 参考 [http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html](http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)
Pre:
Kubernetes调度详解
Next:
Filebeat优化实践
1
likes
589
Weibo
Wechat
Tencent Weibo
QQ Zone
RenRen
Please enable JavaScript to view the
comments powered by Disqus.
comments powered by
Disqus
Table of content