Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在spring security中撤销身份验证令牌?_Java_Spring_Spring Security Oauth2 - Fatal编程技术网

Java 如何在spring security中撤销身份验证令牌?

Java 如何在spring security中撤销身份验证令牌?,java,spring,spring-security-oauth2,Java,Spring,Spring Security Oauth2,在注销控制器中,我试图编写大量的代码组合。现在我有这个: final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { new SecurityContextLogoutHandler().logout(request, response, auth); } SecurityContextHolder.getContext().setAut

在注销控制器中,我试图编写大量的代码组合。现在我有这个:

final Authentication auth = SecurityContextHolder.getContext().getAuthentication();

if (auth != null) {
    new SecurityContextLogoutHandler().logout(request, response, auth);
}

SecurityContextHolder.getContext().setAuthentication(null);
auth.setAuthenticated(false);
但在提供代码执行令牌后仍然有效


我错了什么?如何最终撤销令牌?

您要查找的类是 ,方法
revokeToken(字符串tokenValue)


撤销令牌的控制器示例,以及使用
DefaultServices
bean的oauth2配置。

自动连接DefaultTokenServices,然后使用以下代码:

String authHeader = request.getHeader("Authorization");
String tokenValue = authHeader.replace("bearer", "").trim();
tokenService.revokeToken(tokenValue);
tokenService.setAccessTokenValiditySeconds(1);
tokenService.setRefreshTokenValiditySeconds(1);

只需尝试使用代码来撤销访问令牌。

如果您需要为当前用户以外的其他用户撤销令牌(例如,管理员希望禁用用户帐户),您可以使用以下方法:

Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientIdAndUserName(
                                                           "my_oauth_client_id", 
                                                           user.getUsername());
for (OAuth2AccessToken token : tokens) {
  consumerTokenServices.revokeToken(token.getValue());
}
Collection tokens=tokenStore.findtokensbyclientandusername(
“我的客户id”,
getUsername());
for(OAuth2AccessToken令牌:令牌){
consumerTokenServices.revokeToken(token.getValue());
}

tokenStore
成为
org.springframework.security.oauth2.provider.tokenStore
consumerTokenServices
成为
org.springframework.security.oauth2.provider.token.consumerTokenServices
时,线程有点旧,但对于JWTToken用户来说,这不起作用,因为令牌不起作用存储。 因此,另一种选择是使用过滤器。 1为管理员创建一个方法来锁定/解锁数据库中的用户。 2使用过滤器,如果方法需要验证,则检查用户是否处于活动状态

例如:

@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);
}
在客户端,只需截获此错误并断开用户连接
希望这对某人有所帮助。

当前授权用户使用以下令牌撤销的简单示例:

  • 默认令牌存储需要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);
    }
    }
    

  • @raonirenosto,我在使用您的示例使用Spring Bee代理自动连接类时遇到了问题。我必须将DefaultTokenServices更改为ConsumerTokenServices(这是一个接口)才能工作。但是感谢您建议使用DefaultTokenServices.revokeToken()。自从我上次看到SpringOAuth以来,它已经改变了许多类。我想框架现在比我写这个例子时更稳定了。两个链接都不存在了:(有人应该解释为什么这个答案被否决。为什么不建议这样做?@Olantobi,因为这样更改令牌有效期会更改整个应用程序的令牌有效性,而不仅仅是一个令牌。执行此操作时,其显示“无法对非静态方法revokeToken(String)进行静态引用”从类型ConsumerTokenServices“.Mohammed Shafeek,您必须使用类名来调用方法revokeToken,而不是使用从类ConsumerTokenServicesCA实例化的对象的名称:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为“org.springframework.security.oauth2.provider.token.TokenStore”的合格bean可用:至少需要1个符合autowire候选条件的bean。依赖项批注:{}