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

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跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx动静分离实现负载均衡

转载自 Nginx动静分离实现负载均衡 前期准备 使用Debian环境。安装Nginx(默认安装)&#xff0c;一个web项目&#xff0c;安装tomcat(默认安装)等。 Nginx.conf配置 1 # 定义Nginx运行的用户 和 用户组 如果对应服务器暴露在外面的话建议使用权限较小的用户 防止被入侵2 # …

html5动画是什么,10个HTML5动画 让你忘掉Flash是啥(组图)

你最近可能已经听到了很多关于Flash是面临垂死挣扎的技术以及它将如何很快被HTML5的取代。就个人而言&#xff0c;我认为HTML5会慢慢取代一些Flash的东西&#xff0c;但Flash会永远有它的一席之地&#xff0c;特别是开发复杂的游戏和丰富的互联网应用。如果你还没有看到HTML5动…

2016蓝桥杯省赛---java---A---6(寒假作业)

题目描述 现在小学的数学题目也不是那么好玩的。 看看这个寒假作业&#xff1a;□ □ □ □ - □ □ □ □ □ □ □ □(如果显示不出来&#xff0c;可以参见【图1.jpg】)每个方块代表1~13中的某一个数字&#xff0c;但不能重复。 比如&#xff1a; 6 7 13 9 - 8 1 …

微服务网关Ocelot

微服务网关是微服务架构中的核心组件,它是客户端请求的门户,它是调用具体服务端的桥梁.下面我们将使用开源项目Ocelot&#xff08;https://github.com/geffzhang/Ocelot&#xff09;搭建一款轻量级服务网关,不过在此之前我们将对微服务网关做个详细介绍,以便大家更加清晰的了解…

分表分库时机选择及策略

转载自 分表分库时机选择及策略 一. 分表 应用场景&#xff1a; 对于大型的互联网应用来说&#xff0c;数据库单表的记录行数可能达到千万级甚至是亿级&#xff0c;并且数据库面临着极高的并发访问。采用Master-Slave复制模式的MySQL架构&#xff0c;只能够对数据库的读进…

2015蓝桥杯省赛---java---A---2(星系炸弹)

题目描述 思路分析 方案一 方案二 package TEST;import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;class Main{public static void main(String[] args) {SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-MM-dd");…

NuGet社区使用体验调查

Nuget 是我们使用.NET Core的一项基础设施&#xff0c;针对国内访问NuGet服务器速度不稳定的问题我们希望通过收集一些来自用户的反馈来改善社区使用NuGet的体验。恳请您花2-3分钟时间完成以下的问题&#xff0c;我们会非常重视您的反馈。当我们收集完成所有的问卷&#xff0c;…

在护卫神上部署javaWeb项目,已经测试通过

以前一直在护卫神上部署PHP项目&#xff0c;今天忽然来了需求是部署javaWeb项目&#xff0c;刚开始一脸蒙蔽&#xff0c;后来发现也不是很难。那么接下来我们看看怎么在护卫神上部署java项目&#xff1a; 第一步&#xff1a;打开护卫神&#xff0c;在护卫神中添加一个网站&…

为什么选择微服务架构?如何取舍?

转载自 为什么选择微服务架构&#xff1f;如何取舍&#xff1f; 微服务是什么 微服务是一种架构风格&#xff0c;一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署&#xff0c;各个微服务之间是松耦合的。每个微服务仅关注于完成…

三星系统和鸿蒙系统,又一设备直升鸿蒙系统,现有操作系统被抛弃,和三星的想法一样!...

又一设备直升鸿蒙系统&#xff0c;现有操作系统被抛弃&#xff0c;和三星的想法一样&#xff01;前段时间华为正式发布了鸿蒙系统&#xff0c;这个系统可以说是期待已久了&#xff0c;在华为处于禁令时期时&#xff0c;鸿蒙被认为是替代安卓的操作系统。在鸿蒙发布后&#xff0…

从真实项目中抠出来的设计模式——第一篇:策略模式

有时候因为种种原因导致我们会写出很多丑陋的代码&#xff0c;比如赶工时&#xff0c;短暂性的偷懒&#xff0c;不会设计模式等等导致代码沉积&#xff0c;一个cs上万行代码这样场景是有发生&#xff0c; 当然这里也包括我。。。所以时间充裕一点之后就想重构一下&#xff0c;…

jquery实现单击div切换背景,再次单击回到原来样式

首先来看看效果图&#xff1a; 1.这是默认的的div样式&#xff1a; 2.当我们单击第一个div时的样式&#xff1a; 3.当我们再次单击第一个div时的样式&#xff1a; 如果你需要的效果是这样的&#xff0c;那么请您继续往下面看&#xff0c;如果不是&#xff0c;您也可以看看实…

Java进阶之对象克隆(复制)

转载自 Java进阶之对象克隆&#xff08;复制&#xff09; 假如说你想复制一个简单变量。很简单&#xff1a; int apples 5; int pears apples; 不仅仅是int类型&#xff0c;其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。 但…

如何下载网页中的视频成mp4格式

1.在生活中&#xff0c;我们经常在网页上看到某个视频之后想要下载下来&#xff0c;可是&#xff0c;网上大部分的视频都在几大播放器所占领&#xff0c;比如爱奇艺、优酷、腾讯等等&#xff0c;当你在这些上面下载的时候会发现先要让你下载播放器&#xff0c;才能下载视频。这…

微软CNTK 2.0版本发布,支持C#

微软 CNTK 2.0 版本今天正式发布。 CNTK&#xff08;Cognitive Toolkit&#xff09;是微软的深度学习工具包&#xff0c;可以帮助企业加速图像和语音识别进程。有了今天的更新&#xff0c;企业可以在本地或云端结合 Azure GPU 使用 CNTK了。 伴随着今天的新版本发布&#xff0c…

Android碎片Fragment详讲(1)

Fragment Fragment创建的步骤 1、 继承fragment一定是V4包下的 2、 有且只有一个无参的构造方法 3、 如果Fragment需要显示界面&#xff0c;需要重写onCreateView方法 4、 指定布局资源&#xff0c;或者创建布局&#xff0c;返回即可 静态创建frag…

这些BATJ必考的Java面试题,你都懂了吗?

转载自 这些BATJ必考的Java面试题&#xff0c;你都懂了吗&#xff1f; 题目一 请对比 Exception 和 Error&#xff0c;另外&#xff0c;运行时异常与一般异常有什么区别&#xff1f; 考点分析&#xff1a; 分析 Exception 和 Error 的区别&#xff0c;是从概念角度考察了…

计算机玩游戏特别卡,Win7电脑游戏卡顿怎么办 win7玩游戏卡如何解决

很多人都喜欢在win7系统中玩游戏&#xff0c;而在玩游戏的时候经常会碰到一些故障&#xff0c;比如有很多用户反映的游戏卡顿、玩游戏太卡&#xff0c;这让很多游戏玩家很是苦恼&#xff0c;那么Win7电脑游戏卡顿怎么办呢&#xff1f;下面给大家介绍一下win7玩游戏卡的解决方法…

在IIS上部署你的ASP.NET Core项目

概述 与ASP.NET时代不同&#xff0c;ASP.NET Core不再是由IIS工作进程&#xff08;w3wp.exe&#xff09;托管&#xff0c;而是使用自托管Web服务器&#xff08;Kestrel&#xff09;运行&#xff0c;IIS则是作为反向代理的角色转发请求到Kestrel不同端口的ASP.NET Core程序中&a…

2020蓝桥杯省赛---java---A---2(既分数组)

题目描述 代码实现 package TEST;public class Main {public static void main(String[] args) {int ans 0;for(int i1; i<2020; i)for(int j1; j<2020; j) // if(j>i){{if(gcd(i, j) 1) ans;} // }else { // if(gcd(i, j) …