Reputation: 2959
Spring-OAuth inserts multiple records in the access_token table when the same user logs in from different devices. What should be done to prevent Spring creating multiple access tokens. A user should be able to login from several devices at the same time.
Using 2.0.3.RELEASE
Upvotes: 4
Views: 9606
Reputation: 2102
Just for a workaround, and to handle multiple instances of the service. Just get the token first, and if it is found return it, else then create it.
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;
}
}
Then register it:
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);
}
}
Upvotes: 2
Reputation: 56
I used one of the solutions suggested here and added @Transactional to my AuthorizationServerConfiguration's tokenStore() method.
Adding the @Transactional annotation allowed the same user to login from multiple clients, however, logging out from one client often results in the invalidation of the oauth_access_token (but not always!) and thus other clients were invalidated as well. I'm still looking into that bit...
For what it's worth, I also revved my versions (hopefully that's an option for you) of spring-security-oauth2 to 2.0.9.RELEASE and spring-security-web to 3.2.9.RELEASE.
Upvotes: 0
Reputation: 12182
The TokenStore
s use an AuthenticationKeyGenerator
to create a key which is used to look up access tokens in the store/DB. The DefaultAuthenticationKeyGenerator
that is used by default creates a key using the username, clientId and the scope. If these are the same it returns the same key, which results in the same access token to be returned. Create your own AuthenticationKeyGenerator
and inject it into your TokenStore
instance.
The question is why you want to do that. It really doesn't hurt that a user has multiple tokens. If you want to log out the user on all devices, ping the backend with the username so that it kills all tokens for this user.
Upvotes: 1