弹簧安全。如何注销用户(吊销 oauth2 令牌)

2022-09-01 08:20:06

当我想注销时,我调用以下代码:

request.getSession().invalidate();
SecurityContextHolder.getContext().setAuthentication(null);

但是在它之后(在下一个使用旧oauth令牌的请求中),我调用

SecurityContextHolder.getContext().getAuthentication();

我在那里看到我的老用户。

如何解决?


答案 1

这是我的实现(Spring OAuth2):

@Controller
public class OAuthController {
    @Autowired
    private TokenStore tokenStore;

    @RequestMapping(value = "/oauth/revoke-token", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public void logout(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null) {
            String tokenValue = authHeader.replace("Bearer", "").trim();
            OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
            tokenStore.removeAccessToken(accessToken);
        }
    }
}

对于测试:

curl -X GET -H "Authorization: Bearer $TOKEN" http://localhost:8080/backend/oauth/revoke-token

答案 2

camposer的响应可以使用Spring OAuth提供的API进行改进。实际上,没有必要直接访问 HTTP 标头,但删除访问令牌的 REST 方法可以按如下方式实现:

@Autowired
private AuthorizationServerTokenServices authorizationServerTokenServices;

@Autowired
private ConsumerTokenServices consumerTokenServices;

@RequestMapping("/uaa/logout")
public void logout(Principal principal, HttpServletRequest request, HttpServletResponse response) throws IOException {

    OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) principal;
    OAuth2AccessToken accessToken = authorizationServerTokenServices.getAccessToken(oAuth2Authentication);
    consumerTokenServices.revokeToken(accessToken.getValue());

    String redirectUrl = getLocalContextPathUrl(request)+"/logout?myRedirect="+getRefererUrl(request);
    log.debug("Redirect URL: {}",redirectUrl);

    response.sendRedirect(redirectUrl);

    return;
}

我还添加了一个重定向到Spring Security注销过滤器的端点,因此会话无效,客户端必须再次提供凭据才能访问/oauth/authorize端点。


推荐