我有多个移动客户端,它们都使用密码授予流程进行身份验证。为此,我只想使用一个非常持久的刷新令牌和多个寿命较短的访问令牌。我一直在尝试在春季使用密码授权生成多个访问令牌,但是,每当我刷新访问令牌时,旧的访问令牌就会停止工作。我检查了数据库,并且在oauth_access_token表中始终只有一条记录用于该特定身份验证。 Spring Oauth2是否应该为一个刷新令牌生成多个访问令牌? 谢谢您的帮助。
答案 0 :(得分:0)
OAuth2规范支持它,请参见RFC 6749:
1.5。刷新令牌
刷新令牌是用于获取访问令牌的凭据。刷新 令牌由授权服务器发布给客户端,并且 当当前访问令牌用于获取新的访问令牌 变得无效或过期,或获取其他访问令牌 范围相同或更窄(访问令牌的范围可能更短) 生命周期,且权限少于资源授权 所有者)。
但是Spring Security OAuth2不支持它,请参见DefaultTokenServices#refreshAccessToken
:
// clear out any access tokens already associated with the refresh // token. tokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
和TokenStore#removeAccessTokenUsingRefreshToken
:
使用刷新令牌删除访问令牌。此功能是必需的,因此刷新令牌不能用于创建无限数量的访问令牌。
一种解决方法是实施自定义TokenStore
。
答案 1 :(得分:0)
此处的目标是使多个设备能够彼此独立地使用不同的令牌。事实证明,在Spring OAuth中,我们不能有一个刷新令牌以及与之关联的多个访问令牌。 事实证明,没有必要进行这样的配置。只要我们可以对单独的设备进行单独的身份验证就可以了。现在,将基于client_id,作用域和用户名生成密钥( DefaultAuthenticationKeyGenerator )。由于我没有使用示波器,因此我将设备信息简单地放在了示波器中,并得到了以下信息:
{
"access_token": "32e11a1b-cb9f-4317-95b0-e850f260d160",
"token_type": "bearer",
"refresh_token": "d097e4ea-a9d9-4e0c-94cd-7c15e1c8e690",
"expires_in": 3599,
"scope": "android2",
"exp": 1557843628674
}
要做到这一点,只需省略示波器配置,如下所示:
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(CLIENT_ID)
.secret(passwordEncoder.encode(CLIENT_SECRET))
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT)
// ************* Comment this out ******
//.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS);
}
使用此方法,每个设备都可以获取单独的令牌。此外,当用户注销时,我们可以选择从所有设备中注销他。 但是,我们不能在请求中忽略范围;必须始终在刷新令牌请求中发送scope参数。