Reputation: 37034
In logout controller I tryed to write a lot of combination of code. Now I have this:
final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
new SecurityContextLogoutHandler().logout(request, response, auth);
}
SecurityContextHolder.getContext().setAuthentication(null);
auth.setAuthenticated(false);
But after provided code execution token still valid.
What do I wrong? How to revoke token eventually?
Upvotes: 11
Views: 29537
Reputation: 148
Simple example of token revocation for current authorized user using DefaultTokenServices:
Need Bean for Default token store
@Bean
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
Then you can write your own controller
@RestController
@RequestMapping("/user")
public class UserApi {
@Autowired
private DefaultTokenServices tokenServices;
@Autowired
private TokenStore tokenStore;
@DeleteMapping("/logout")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void revokeToken() {
final OAuth2Authentication auth = (OAuth2Authentication) SecurityContextHolder
.getContext().getAuthentication();
final String token = tokenStore.getAccessToken(auth).getValue();
tokenServices.revokeToken(token);
}
}
Upvotes: 0
Reputation: 834
the thread is a bit old but for JWTToken users this is not working as the tokens are not stored. So another option is to use a filter. 1 create a method for admin to lock/unlock a user on your database. 2 use a filter and if the method needs authentication check if the user is active or not
exemple :
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null
&& authentication.getName() != null
&& !authentication.getName().equalsIgnoreCase("anonymousUser")) {
UserModel user = userService.getUser(authentication.getName());
if(user != null && !user.isActivated())
throw new SecurityException("SECURITY_USER_DISABLED");
}
chain.doFilter(request, response);
}
On client side just intercept this error and disconnect user hope this helps someone.
Upvotes: 0
Reputation: 1515
The class you're looking for is
DefaultServices
, method revokeToken(String tokenValue)
.
Here an exemple of a controller that revokes token, and here the oauth2 configuration with the DefaultServices
bean.
Upvotes: 8
Reputation: 26848
If you need to revoke a token for another user than the current one (E.g. an admin wants to disable a user account), you can use this:
Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientIdAndUserName(
"my_oauth_client_id",
user.getUsername());
for (OAuth2AccessToken token : tokens) {
consumerTokenServices.revokeToken(token.getValue());
}
With tokenStore
being an org.springframework.security.oauth2.provider.token.TokenStore
and consumerTokenServices
being a org.springframework.security.oauth2.provider.token.ConsumerTokenServices
Upvotes: 9
Reputation: 1
Autowire the DefaultTokenServices then use this code:
String authHeader = request.getHeader("Authorization");
String tokenValue = authHeader.replace("bearer", "").trim();
tokenService.revokeToken(tokenValue);
tokenService.setAccessTokenValiditySeconds(1);
tokenService.setRefreshTokenValiditySeconds(1);
Just try the code to revoke the access token.
Upvotes: -3