Java 如何在 Spring Security 中撤销 auth 令牌?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21992201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to revoke auth token in spring security?
提问by gstackoverflow
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?
我怎么了?最终如何撤销令牌?
采纳答案by raonirenosto
The class you're looking for is
DefaultServices
, method revokeToken(String tokenValue)
.
您要查找的类是
DefaultServices
, method revokeToken(String tokenValue)
。
Herean exemple of a controller that revokes token, and herethe oauth2 configuration with the DefaultServices
bean.
回答by Suresh.U
Autowire the DefaultTokenServices then use this code:
自动装配 DefaultTokenServices 然后使用以下代码:
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.
只需尝试代码以撤销访问令牌。
回答by Wim Deblauwe
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
随着tokenStore
作为一个org.springframework.security.oauth2.provider.token.TokenStore
和consumerTokenServices
作为一个org.springframework.security.oauth2.provider.token.ConsumerTokenServices
回答by mcfly
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
该线程有点旧,但对于 JWTToken 用户而言,这不起作用,因为未存储令牌。所以另一种选择是使用过滤器。1 为管理员创建一个方法来锁定/解锁数据库上的用户。2 使用过滤器,如果该方法需要身份验证检查用户是否处于活动状态
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.
在客户端,只需拦截此错误并断开用户连接,希望这对某人有所帮助。
回答by lukascode
Simple example of token revocation for current authorized user using DefaultTokenServices:
使用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); } }
需要 Bean 用于默认令牌存储
@Bean public DefaultTokenServices tokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setTokenStore(tokenStore()); defaultTokenServices.setSupportRefreshToken(true); return defaultTokenServices; }
然后你可以编写自己的控制器
@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); } }