OAuth 2.1的状态与主要特征

经过多年的OAuth 2.0协议的发展,最新版本的 OAuth 2.1 协议已经在进行中,可访问 https://oauth.net/2.1/ 获取最新的相关信息。

2.1版本相比2.0版本的优化或不同点有:

OAuth 2.1

简单点说就是:

  • PKCE变成必须的了
  • Redrect URI的检查更严格
  • grant_type中的password, implicit都不再推荐使用(甚至不再支持)
  • 不再允许通过URL查询参数传递access_token(甚至不再支持)
  • 刷新token增加约束限制(如一次性刷新)

OAuth2.1将变得更加安全,从流程定义与各个端(endpoint)来讲;这也符合网络环境越来越复杂,安全问题越来越高的实际场景。相比传统的client端浏览器与APP来讲,未来的client端会更多样,如智能家居设备,穿戴设备,工业互联设备等。

从另一个方面来说,认证凭证(如常见的 密码)将趋于在授权服务(Authorization Server)中统一进行管理,认证的操作收归到授权服务器端来管控,不再放由client端可知晓(想想grant_type=password中可通过API传递用户凭证是多么的信任client端啊)。

OAuth2中token升级使用JWT的实现参考

OAuth2中默认使用 Bearer Tokens (一般用UUID值)作为token的数据格式,但也支持升级使用JSON Web Token(JWT)来作为token的数据格式。

20200918101526

下面以 spring-oauth-server 升级使用JWT来说明

重点在于提供一个 JwtTokenStore的配置类,详细可参见 MyOIDC 工程中的配置:https://gitee.com/mkk/MyOIDC/blob/master/myoidc-server/src/main/java/myoidc/server/config/OAuth2ServerConfiguration.java

需要注意的是底层使用的算法,可以是RSA也可以对称加密的HMAC等,具体可查看 JwtAccessTokenConverter.java 类。

对应的工程中需要增加 spring-security-jwt 库的依赖(如果是Maven工程)。

 

OIDC中的术语介绍与示例

 

以下对OIDC主要的术语进行说明,并与OAuth2作相关对比。

  • EU End-User, 指用户(一般指有账号的个体,资源的拥有者)
  • RP Relying Party, 信任方(一般是一个软件应用), 理解为OAuth2中的客户端(client)即可, 需要在OP中注册
  • OP OpenID Provider, 能提供对EU进行认证的服务端(可理解为OAuth2中授权服务端),
    提供RP的注册(或管理)能力,EU管理,ID Token的签发与管理等。OIDC中的核心组件。
    OIDC-Server 就是一个OP的参考实现
  • ID Token 格式为JSON Web Token(JWT),
    包含EU认证授权信息等. 有关JWT请访问 https://jwt.io/除了JWT, 知道以下概念对掌握OIDC会很有帮助
    JSON Web Key(JWK),
    JSON Web Encryption(JWE),
    JSON Web Algorithm(JWA),
    JSON Web Signature(JWS)
  • UserInfo Endpoint EU信息接口(OAuth2保护), 在RP获取到access_token后,可调用此接口获取EU的详细信息.
    OIDC要求此接口必须使用https访问(更安全);一般在OP中提供的Discovery中获取
  • Claim EU信息的载体, 可在id_token中获取,主要包括认证信息与授权信息,可根据实际扩展
  • 查看完整术语定义请访问 https://openid.net/specs/openid-connect-core-1_0.html#Terminology

OIDC协议中抽象了一个主要的操作步骤与流程示意图,如下:

20200920150958

下面以AWS提供的OIDC服务来举例说明。 假设你现在有一个应用A想集成使用AWS的OIDC服务,在实现OIDC之前需要先做几件事

  1. 应用A(RP)先去AWS(OP)中注册一个应用并获取对应的client_id, client_secret,public key等信息( 一般这步骤是开发者去完成)。注册时一般需要提供应用名称,redirect_uri等信息。
  2. 根据AWS提供的实现文档进行应用A(RP)的集成(也是开发者完成)。

OIDC流程在此示例中的关系图如下:

20200920151748

结束。

 

详细完整的使用请访问 MyOIDC: https://gitee.com/mkk/MyOIDC

 

spring-oauth-server 2.0.2 发布,扩展 OAuth2 Server

spring-oauth-server在2020-06-04更新发布了2.0.2版本,spring-oauth-server是Spring与Oauth2整合示例。

此版本更新内容如下:

1.Fix CVE-2019-3778, use spring-security-oauth 2.3.5.RELEASE

2.解决数据库多条 access_token问题,增加唯一约束

3.升级Spring-Boot版本为2.1.4.RELEASE

 

2.0.2版本release链接: https://gitee.com/shengzhao/spring-oauth-server/releases

 

MyOIDC v1.1.1 发布,基于 OIDC 协议的参考实现,根据各类库提供实现参考

MyOIDC  –基于OIDC协议的参考实现,根据各类库提供实现参考 。正式版本v1.1.1发布,主要更新内容:

  1. 修改启动方法为jar直接运行
  2. 更新How-To-Use.txt
  3. AccessToken使用时允许获取更详细用户信息
  4. 增加 JWKS test与使用说明示例
  5. jose4j升级使用0.7.1版本

openid

GitHub:   https://github.com/monkeyk/MyOIDC/tree/v1.1.1

Gitee:  https://gitee.com/mkk/MyOIDC/tree/v1.1.1

OAuth2中 access_token,refresh_token的各类配置与使用场景FAQ

过去几年的OAuth2经历与使用,总结一下,记录有关 access_token, refresh_token的各类配置与场景适应,到此以自问自答的形式把这些琐碎的点总结下来。

说明:以下问答中的截图或表等信息以 spring-oauth-server 中配置为参考。

 

> 问:可以设置永不过期的 refresh_token吗?

答:可以,需要按以下步骤操作:首先在client_details定义中不设置 refresh_token_validity 字段值(即默认null),其次在配置OAuth2的DefaultTokenServices时将refreshTokenValiditySeconds属性值配置为0或小于0(默认为30天,若想修改为其他默认值也在此配置),关键代码看下图

111

 

> 问:可以设置永不过期的 access_token吗?

答:可以,但不推荐使用(因为永不过期意味着除手动清除外无安全性可言);若需要按以下步骤操作:首先在client_details定义中不设置 access_token_validity字段值(即默认null),其次在配置OAuth2的DefaultTokenServices时将accessTokenValiditySeconds属性值配置为0或小于0(默认为12小时,若想修改为其他默认值也在此配置),关键代码看下图

8888

 

> 问:refresh_token功能可以禁用吗?

答:可以,首先要求client_details的grant_type不支持 refresh_token,即authorized_grant_types字段中无 refresh_token,其次在配置OAuth2的DefaultTokenServices时将supportRefreshToken配置为false即可,关键代码看下图

222

 

> 问:默认的 access_token有效时间是多少?默认的 refresh_token有效时间是多少?在哪看

答:默认access_token有效时间为12小时,默认refresh_token有效时间为30天,这两默认值在OAuth2的DefaultTokenServices中定义的,如下图:

3333

若想改变默认值,只需要在定义client_details是修改字段access_token_validity (access_token有效时间)与 refresh_token_validity (refresh_token有效时间),单位为:秒

 

> 问:可否在每次调用 refresh token操作时重新生成一个 refresh_token值?若可以如何做

答:可以支持此功能,具体为在配置OAuth2的DefaultTokenServices时将reuseRefreshToken属性配置为fasle即可(默认true),关键代码看下图

44

 

> 问:能否在生成access_token后加自己扩展的代码逻辑?若能如何做

答:可以加自己的扩展逻辑。首先需要写一个类实现接口 TokenEnhancer.java ,实现方法 enhance方法,一示例如下:

555

其次在配置 OAuth2的DefaultTokenServices时增加tokenEnhancer属性配置,关联扩展实现的类即可,关键代码如下

6666

实际上Spring Security OAuth2中实现JWT从而支持OIDC流程就是扩展TokenEnhancer.java来实现的(有一个实现类 JwtAccessTokenConverter.java)

 

> 问:生成access_token值是一UUID值吧?能否不使用UUID值,想扩展如何办?

答:确实生成的access_token是一UUID值,若要扩展不使用UUID,需要这样做:首先写一个子类继承DefaultTokenServices.java,其次将DefaultTokenServices.java的源代码复制到扩展的子类中,并修改createAccessToken方法与createRefreshToken方法中的代码(如此做是因为两方法定义的private的),关键代码如下

7777

另一种办法是通过扩展TokenEnhancer.java 来实现(详细见上一问答)

 

> 问:如何提高 access_token, refresh_token的性能,默认存储在数据库中在高并发大数据时数据库连接会成为性能瓶颈的

答:在大数据高并发环境时,建议使用Redis,将access_token, refresh_token存储在Redis中实现,具体在配置OAuth2的TokenStore时使用子类 RedisTokenStore(默认使用的子类为JdbcTokenStore),更多信息请查看 http://andaily.com/blog/?p=19776

 

 

 

 

MyOIDC v1.1.0 发布–基于OIDC协议的参考实现,根据各类库提供实现参考

MyOIDC  –基于OIDC协议的参考实现,根据各类库提供实现参考 。第1个正式版本v1.1.0发布,主要更新内容:

  1. 实现OIDC协议的主要流程,包括 DiscoveryEndpoint等各类Endpoint提供实现参考;实现OIDC中主要的认证授权流程;JWKS API实现等。
  2. 实现myoidc-server, myoidc-client 两模块的各类功能细节,能实际使用,形成操作闭环。
  3. openid

V1.1.0 代码库链接:

GitHub:  https://github.com/monkeyk/MyOIDC/tree/v1.1.0

Gitee: https://gitee.com/mkk/MyOIDC/tree/v1.1.0/