0. RFC6749还有哪些可以完善的?

0.1. 撤销Token

在上篇[认证授权] 1.OAuth2授权 中介绍到了OAuth2可以帮我们解决第三方Client访问受保护资源的问题,但是只提供了如何获得access_token,并未说明怎么来撤销一个access_token。关于这部分OAuth2单独定义了一个RFC7009 - OAuth 2.0 Token Revocation来解决撤销Token问题。

0.2. Token对Client的不透明问题

OAuth2提供的“access_token"是一个对Client不透明的字符串,尽管有"scope","expires_in"和"refresh_token"来辅助,但也是不完善的且分散的信息。还拿上一篇的小明来举例,“小明授权在线打印并且包邮的网站访问自己的QQ空间相册”。双引号里面的这句话其中有4个重要的概念:

  1. 授权者小明:表示是小明授权,而不是隔壁老王。

  2. 被授权者在线打印并且包邮的网站:表示授权给指定的网站,而不是其他的比如1024.com之类的网站(你懂的。。。)。

  3. 小明自己的QQ空间:表示让被授权者访问自己的信息,而不是隔壁老王的信息,小明也没这权限来着,不然隔壁王婶夜不答应吧。。。

  4. 相册:表示你可以访问我的相册,而不是我的日志,我的其他信息。

那么如何得到获得上面提到的这些附加的信息呢?OAuth2又单独提供了一个RFC7662 -OAuth 2.0 Token Introspection来解决Token的描述信息不完整的问题。

1. OAuth2 Token 撤销(RFC7009 - OAuth2 Token Revocation)

简单来说,这个协议规定了一个Authorization server提供一个怎样的API来供Client撤销access_token或者refresh_token。

比如Client发起一个如下的请求:

POST /revoke HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token

其中各项含义如下:

  1. /revoke:是Authorization Server需要提供的API地址,Client使用Post方式请求这个地址。

  2. Content-Type: application/x-www-form-urlencoded:固定此格式。

  3. Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW:访问受保护资源的授权凭证。

  4. token:必选,可以是access_token或者refresh_token的内容。

  5. token_type_hint:可选,表示token的类型,值为”access_token“或者"refresh_token"。

如果撤销成功,则返回一个HTTP status code为200的响应就可以了。

2. OAuth2 Token 元数据(RFC7662 - OAuth2 Token Introspection)

简单的总结来说,这个规范是为OAuth2扩展了一个API接口(Introspection Endpoint),让第三方Client可以查询上面提到的那些信息(比如,access_token是否还有效,谁颁发的,颁发给谁的,scope又哪些等等的元数据信息)。

比如Client发起一个如下的请求:

POST /introspect HTTP/1.1
Host: server.example.com
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer 23410913-abewfq.123483

token=2YotnFZFEjr1zCsicMWpAA&token_type_hint=access_token

看起来和上面的撤销Token的请求差不多,其中各项含义如下:

  1. /introspect:是Authorization Server需要提供的API地址,Client使用Post方式请求这个地址。

  2. Accept:application/json:表示Authorization Server需要返回一个JSON格式的数据。

  3. Content-Type: application/x-www-form-urlencoded:固定此格式。

  4. Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW:访问受保护资源的授权凭证。

  5. token:必选,可以是access_token或者refresh_token的内容。

  6. token_type_hint:可选,表示token的类型,值为”access_token“或者"refresh_token"。

如果请求成功,则会返回如下的信息:

{

"active": true,

"client_id": "l238j323ds-23ij4",

"token_type":"access_token",

"username": "jdoe",

"scope": "read write dolphin",

"sub": "Z5O3upPC88QrAjx00dis",

"aud": "https://protected.example.net/resource",

"iss": "https://server.example.com/",

"exp": 1419356238,

"iat": 1419350238,

"nbf": 1419350238,

"jti": "abcdefg"

"extension_field": "twenty-seven"

}

JSON各项属性含义如下(其中有些信息是在JSON Web Token中定义的,参考链接有详细的介绍):

  1. active:必须的。表示token是否还是有效的。

  2. client_id:可选的。表示token所属的Client。比如上面的在线打印并且包邮的网站

  3. token_type:可选的。表示token的类型。对应传递的token_type_hint。

  4. user_name:可选的。表示token的授权者的名字。比如上面的小明

  5. scope:可选的。和上篇5.1.1 Authorization Request中的可选参数scope对应,表示授权给Client访问的范围,比如是相册,而不是小明的日志以及其他受保护资源。

  6. sub:可选的。token所属的资源拥有者的唯一标识,JWT定义的。也就是小明的唯一标识符。

  7. aud:可选的。token颁发给谁的,JWT定义的。

  8. iss:可选的。token的颁发者,JWT定义的。

  9. exp:可选的。token的过期时间,JWT定义的。

  10. iat:可选的。iss颁发token的时间,JWT定义的。

  11. nbf:可选的。token不会在这个时间之前被使用,JWT定义的。

  12. jti:可选的。token的唯一标识,JWT定义的。

  13. extension_field:可以自己扩展相关其他属性。

其中大量的信息都是可选的信息,而且可以自己扩展需要的属性信息,从这些属性中就可以解决我们上面提到的access_token对于Client不透明的问题。

我们注意到其中有很多属于JWT定义的属性,那么这个JWT是什么东西?它解决了什么问题?

3. JSON Web Token (JWT)

简单总结来说,JWT是一个定义一种紧凑的自描述的并且提供防篡改机制的传递数据的方式的标准协议。

我们先来看一个简单的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9.hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk

就是这么一堆看起来像是乱码一样的字符串。JWT由3部分构成:header.payload.signature,每个部分由“.”来分割开来。

3.1. Header

header是一个有效的JSON,其中通常包含了两部分:token类型和加密算法。

{"alg": "HS256","typ": "JWT"
}

对这个JSON采用base64编码后就是第1部分eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。

3.2. Payload

这一部分代表真正想要传递的数据,包含一组Claims,其中JWT预定义了一些Claim(2. Token 元数据 这一节就用到一些JWT预定义的一些Cliam)后面会介绍。关于什么是Claim,可以参考文章末尾给的参考链接。

{"sub": "1234567890","name": "linianhui"
}

对这个JSON采用base64编码后就是第2部分eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9。

3.3. Signature

这一部分是可选的,由于前面Header和Payload部分是明文的信息,所以这一部分的意义在于保障信息不被篡改用的,生成这部分的方式如下:

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

使用header中指定的签名算法对“header.payload”部分进行签名,得到的第3部分hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk。然后组合成一个完整的JWT字符串,而接收方使用同样的签名算法来生成签名,来判断header和payload部分有没有被篡改锅,因为签名的密钥是只有通信双方知道的,所以可以保证这部分信息不被第三方所篡改。

3.4. JWT的一些Claims

JWT规范中预先定义了一些Cliam,但并不是必选的,常用的有:

  1. iss(Issuer签发者)

  2. sub(subject签发给的受众,在Issuer范围内是唯一的)

  3. aud(Audience接收方)

  4. exp(Expiration Time过期时间)

  5. iat(Issued At签发时间)等等。

更完整的一些Claim列表参见:https://www.iana.org/assignments/jwt/jwt.xhtml

如果上面这些仍无法满足自己的需要,则可以自定义一些来使用。

3.5. JWT 应用场景

由于其采用base64来进行编码,使得它可以安全的用在一些仅限ASCII的地方传递信息,比如URL的querystring中。

比如用户登陆后,可以把用户的一些属性信息(用户标识,是否是管理员,权限有哪些等等可以公开的信息)用JWT编码存储在cookie中,由于其自描述的性质,每次服务器读取到Cookie的时候就可以解析到当前用户对应的属性信息,而不必再次去查询数据库。如果Cookie中每次都发送浪费带宽,也可以用 Authorization: Bearer <jwttoken> 的方式附加到Request上去。

4. OAuth2 & JWT

注意到我们在2. Token 元数据 这一小节中,OAuth2返回Token的元数据的JSON,以及OAuth2中的access_token对Client是不透明的字符串这件事,我们可以把access_token的元数据信息用JWT来编码以下,作为access_token的字符串内容,这样是不是就可以使得它对Client是透明的了。

比如我之前遇到的问题,在我使用access_token的时候有没有过期我并不知道,其实需要借助辅助的“expires_in”来检查,还有其scope是哪些,也需要额外的去查询,再比如这个access_token管理的用户是谁,也需要额外的查询,有了JWT呢,可以把这些都打包进去,比如:

{

"sub":"linianhui",

"scope":"1419356238",

"exp":123456789,

}

然后生成一个这样的jwt字符串 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsaW5pYW5odWkiLCJzY29wZSI6IjE0MTkzNTYyMzgiLCJleHAiOjEyMzQ1Njc4OX0.ASu85ohHMSOhnxbJSJI4OKLsPlbjPs7th0Xw5-b4l1A 作为access_token的值,感觉一下子就方便了好多吧。

5. 总结

OAuth2在RFC6749中并未完整的提供一些问题的解决方案,而是附加了一些相关的RFC来解决这些问题,其实除了本文中提到的2个问题点之外,还有一些其他可以优化的地方存在,这些点在后续的OIDC的文章中再做介绍吧,感兴趣的可以看一看http://openid.net/connect/中关于OAuth2的另外一些相关扩展标准草案,这些标准也是OIDC所需要的一些可选支持。另外在一些场景下,使用JWT来使得OAuth2的提供自描述的Token还是一件很方便的事情的。

以上内容均是个人的一些理解,如果错误之处,欢迎指正!

6. 参考

JSON协议:RFC7159 - The JavaScript Object Notation (JSON) Data Interchange Format

OAuth2 扩展协议:

RFC7009 - OAuth 2.0 Token Revocation

RFC7662 - OAuth 2.0 Token Introspection

OAuth相关扩展草案:https://datatracker.ietf.org/wg/oauth/charter/

JWT相关协议族:

RFC7515 - JSON Web Signature (JWS)

RFC7516 - JSON Web Encryption (JWE)

RFC7517 - JSON Web Key (JWK)

RFC7518 - JSON Web Algorithms (JWA)

RFC7519 - JSON Web Token (JWT)

JWT官方站点:https://jwt.io

Claims:https://en.wikipedia.org/wiki/Claims-based_identity

JWT注册的的一组Claims : https://www.iana.org/assignments/jwt/jwt.xhtml

相关文章:

  • Thinktecture IdentityServer:.NET开源OpenID和OAuth解决方案

  • 教你实践ASP.NET Core Authorization(免看文档教程)

  • 双重OAuth 2.0架构

  • [认证授权] 1.OAuth2授权

原文地址:http://www.cnblogs.com/linianhui/p/oauth2-extensions-protocol-and-json-web-token.html

.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

[认证授权] 2.OAuth2授权(续) amp;amp; JSON Web Token相关推荐

  1. jwt的token自动续约_JWT(JSON Web Token)自动延长到期时间

    cchamberlain.. 6 如果您使用的是节点(React/Redux/Universal JS),则可以安装npm i -S jwt-autorefresh. 此库根据用户计算的访问令牌到期之 ...

  2. JSON Web Token(缩写 JWT) 目前最流行的跨域认证解决方案

    JSON Web Token(缩写 JWT) 目前最流行的跨域认证解决方案 参考文章: (1)JSON Web Token(缩写 JWT) 目前最流行的跨域认证解决方案 (2)https://www. ...

  3. 后端架构token授权认证机制:spring security JSON Web Token(JWT)简例

    后端架构token授权认证机制:spring security JSON Web Token(JWT)简例 在基于token的客户端-服务器端认证授权以前,前端到服务器端的认证-授权通常是基于sess ...

  4. JSON Web Token(缩写 JWT) 目前最流行、最常见的跨域认证解决方案,前端后端都需要会使用的东西

    JSON Web Token(缩写 JWT)是目前最流行,也是最常见的跨域认证解决方案.无论是咱们后端小伙伴,还是前端小伙伴对都是需要了解. 本文介绍它的原理.使用场景.用法. 关于封面:这个冬天你过 ...

  5. 理解JWT(JSON Web Token)认证及python实践

    最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式. 这一篇主要内容是 JWT 的认证原理,以及p ...

  6. python token认证_理解JWT(JSON Web Token)认证及python实践

    最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式. 这一篇主要内容是 JWT 的认证原理,以及p ...

  7. JWT(Json web token)认证详解

    JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...

  8. JWT—JSON Web Token - 理解JWT网络间应用用户安全认证交互设计

    原文地址:http://blog.leapoahead.com/2015/09/06/understanding-jwt/ 官网地址:https://jwt.io/ JSON Web Token(JW ...

  9. php oauth2 和 jwt,jwt-auth: thinkphp 的 jwt (JSON Web Token)身份验证扩展包,支持Swoole...

    JWT-AUTH thinkphp的jwt(JSON Web Token)身份验证包.支持Header.Cookie.Param等多种传参方式.包含:验证.验证并且自动刷新等多种中间件. 支持Swoo ...

最新文章

  1. Vue.js Class 与 Style 绑定
  2. Navicat——连接SQL Server数据库方法
  3. Go语言学习教程:xorm表基本操作及高级操作
  4. WIN10下怎么找到MYSQL5.7数据库中存储数据的位置以及重装mysql数据复盘
  5. CentOS下安装SVN
  6. BXP网卡换槽之后就要按“任意键”的问题解决方法!(转)
  7. MATLAB数值计算函数汇总
  8. 10分钟带你读完人工智能的三生三世
  9. [Leetcode] 448. Find All Numbers Disappeared in an Array 解题报告
  10. 基于SBO程序开发框架的实例:仓库扩展属性设置
  11. 数字+字母+特殊字符 的正则表达式
  12. OllyDBG 入门系列(五)-消息断点及 RUN 跟踪
  13. 杨校老师课堂之集群内SSH免密登录功能配置
  14. 如何在云服务器安装操作系统
  15. oracle 000000000A2F6630,数据导入新库时发生错误
  16. 如何进行日内趋势量化交易系统的设计?这篇文章可以给你启发!
  17. 网络安全学习2个月,感觉什么都不会?
  18. Java阿里云发送短信
  19. 蝉知自定义HTML,如何安装蝉知主题
  20. linux shell 改变前景色和背景色

热门文章

  1. DOM 事件深入浅出(二)
  2. linux学习-简单命令介绍及安装VMware Tools
  3. Oracle 常用sql场景应用(未完待续......)
  4. crontab定时任务中文乱码问题
  5. 路遥工具箱全面迁移至 .NET 6.0 并发布 3.0 版本及迁移记录详解
  6. WTM框架使用技巧之:CI/DI(持续集成/持续部署)
  7. 利用 PGO 提升 .NET 程序性能
  8. 微软放弃IE浏览器 应尽快完成国产化替代
  9. 一文说通Dotnet操作MongoDB GridFS
  10. Dotnet的数据定位和匹配