【发布时间】:2016-06-25 03:47:30
【问题描述】:
当同一用户从不同设备登录时,Spring-OAuth 会在 access_token 表中插入多条记录。应该做些什么来防止 Spring 创建多个访问令牌。一个用户应该能够同时从多个设备登录。
使用 2.0.3.RELEASE
【问题讨论】:
-
你还有这个问题吗?
标签: java spring-security oauth-2.0 spring-boot
当同一用户从不同设备登录时,Spring-OAuth 会在 access_token 表中插入多条记录。应该做些什么来防止 Spring 创建多个访问令牌。一个用户应该能够同时从多个设备登录。
使用 2.0.3.RELEASE
【问题讨论】:
标签: java spring-security oauth-2.0 spring-boot
只是为了解决方法,并处理服务的多个实例。只需先获取令牌,如果找到则返回它,否则创建它。
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);
}
}
【讨论】:
我使用了here 建议的解决方案之一,并将@Transactional 添加到我的 AuthorizationServerConfiguration 的 tokenStore() 方法中。
添加@Transactional 注释允许同一用户从多个客户端登录,但是,从一个客户端注销通常会导致 oauth_access_token 失效(但并非总是如此!),因此其他客户端也会失效。我还在研究那一点...
为了它的价值,我还将我的 spring-security-oauth2 版本(希望这是你的一个选项)升级到 2.0.9.RELEASE 和 spring-security-web 到 3.2.9.RELEASE。
【讨论】:
TokenStores 使用AuthenticationKeyGenerator 创建一个密钥,用于在存储/数据库中查找访问令牌。默认使用的DefaultAuthenticationKeyGenerator 使用用户名、clientId 和范围创建密钥。如果它们相同,则返回相同的密钥,从而返回相同的访问令牌。创建您自己的 AuthenticationKeyGenerator 并将其注入您的 TokenStore 实例。
问题是您为什么要这样做。用户拥有多个令牌确实没有什么坏处。如果您想在所有设备上注销用户,请使用用户名 ping 后端,以便它杀死该用户的所有令牌。
【讨论】: