【问题标题】:Spring Boot OAuth - Multiple Access Tokens for same userSpring Boot OAuth - 同一用户的多个访问令牌
【发布时间】:2016-06-25 03:47:30
【问题描述】:

当同一用户从不同设备登录时,Spring-OAuth 会在 access_token 表中插入多条记录。应该做些什么来防止 Spring 创建多个访问令牌。一个用户应该能够同时从多个设备登录。

使用 2.0.3.RELEASE

【问题讨论】:

  • 你还有这个问题吗?

标签: java spring-security oauth-2.0 spring-boot


【解决方案1】:

只是为了解决方法,并处理服务的多个实例。只需先获取令牌,如果找到则返回它,否则创建它。

public class OAuthTokenServices extends DefaultTokenServices {
    @Override
    public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
        OAuth2AccessToken token = super.getAccessToken(authentication);
        try {
            if (Objects.isNull(token) || token.isExpired()) {
                return super.createAccessToken(authentication);
            }
        } catch (DuplicateKeyException dke) {
            log.info("Duplicate key found. Lets get it instead.");
            token = super.getAccessToken(authentication);
            log.info("We got the token. {}", token);
            return token;
        } catch (Exception ex) {
            log.info(String.format("Exception while creating access token %s", ex));
        }
        return token;
    }
}

然后注册:

public class OAuthAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    DefaultTokenServices tokenServices;

    @Autowired
    private TokenStore tokenStore;

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        OAuthTokenServices tokenService = new OAuthTokenServices();
        tokenService.setTokenStore(tokenStore);
        tokenService.setSupportRefreshToken(true);
        return tokenService;
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.tokenServices(tokenServices);
    }

}

【讨论】:

    【解决方案2】:

    我使用了here 建议的解决方案之一,并将@Transactional 添加到我的 AuthorizationServerConfiguration 的 tokenStore() 方法中。

    添加@Transactional 注释允许同一用户从多个客户端登录,但是,从一个客户端注销通常会导致 oauth_access_token 失效(但并非总是如此!),因此其他客户端也会失效。我还在研究那一点...

    为了它的价值,我还将我的 spring-security-oauth2 版本(希望这是你的一个选项)升级到 2.0.9.RELEASE 和 spring-security-web 到 3.2.9.RELEASE。

    【讨论】:

      【解决方案3】:

      TokenStores 使用AuthenticationKeyGenerator 创建一个密钥,用于在存储/数据库中查找访问令牌。默认使用的DefaultAuthenticationKeyGenerator 使用用户名、clientId 和范围创建密钥。如果它们相同,则返回相同的密钥,从而返回相同的访问令牌。创建您自己的 AuthenticationKeyGenerator 并将其注入您的 TokenStore 实例。

      问题是您为什么要这样做。用户拥有多个令牌确实没有什么坏处。如果您想在所有设备上注销用户,请使用用户名 ping 后端,以便它杀死该用户的所有令牌。

      【讨论】:

      • DefaultAuthenticationKeyGenerator 不会为给定的用户名、clientId 和范围生成相同的令牌。所以它创建了多个令牌。并且多个令牌导致了一个问题,当设备请求一个令牌时,当它期望一个时有多个条目,所以我得到一个“时间戳”:1457604304818,“状态”:500,“错误”:“内部服务器错误","exception":"org.springframework.dao.IncorrectResultSizeDataAccessException","message":"不正确的结果大小:预期 1,实际 2",
      猜你喜欢
      • 1970-01-01
      • 2020-01-28
      • 2018-11-22
      • 2020-02-08
      • 1970-01-01
      • 2018-09-28
      • 2011-09-08
      • 1970-01-01
      • 2019-07-23
      相关资源
      最近更新 更多