具有一个刷新令牌的多路访问令牌

时间:2019-05-12 20:50:29

标签: spring spring-security oauth-2.0 spring-security-oauth2

我有多个移动客户端,它们都使用密码授予流程进行身份验证。为此,我只想使用一个非常持久的刷新令牌和多个寿命较短的访问令牌。我一直在尝试在春季使用密码授权生成多个访问令牌,但是,每当我刷新访问令牌时,旧的访问令牌就会停止工作。我检查了数据库,并且在oauth_access_token表中始终只有一条记录用于该特定身份验证。 Spring Oauth2是否应该为一个刷新令牌生成多个访问令牌? 谢谢您的帮助。

2 个答案:

答案 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参数。