【问题标题】:Multiple Access token with one refresh token具有一个刷新令牌的多访问令牌
【发布时间】:2019-09-29 21:13:30
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    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

    【讨论】:

    • 好答案。我们将自定义令牌存储配置为在通过刷新令牌删除时仅删除过期的访问令牌。这样一来,您就可以让多个设备的同一个用户共享同一个刷新令牌,但每个设备都有一个单独的访问令牌。
    【解决方案2】:

    这里的目标是使多个设备能够彼此独立地使用不同的令牌。事实证明,在 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);
        }
    

    使用这种方法,每台设备都可以获得一个单独的令牌。此外,当用户注销时,我们可以选择将他从所有设备中注销。 但是,我们不能在我们的请求中遗漏范围;范围参数必须始终在刷新令牌请求中发送。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-13
      • 2022-10-31
      • 2019-06-29
      • 1970-01-01
      • 2020-07-12
      • 2020-01-09
      • 2021-08-23
      • 2015-04-01
      相关资源
      最近更新 更多