注销在Spring Security OAuth2中无法正常运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了注销在Spring Security OAuth2中无法正常运行相关的知识,希望对你有一定的参考价值。

有一个Zuul网关作为Spring-Security-OAuth2客户端和授权服务器。这些都位于here

Zuul配置部分:

http
                .csrf()
                .disable()
                .headers().cacheControl().disable()
             .and()
                .headers()
                .cacheControl()
                .disable()
                .frameOptions()
                .sameOrigin()
             .and()
                .httpBasic().disable()
                .authorizeRequests()
                .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                .mvcMatchers("/uaa/**", "/login**", "/favicon.ico", "/error**").permitAll()
                .anyRequest().authenticated()
             .and()
                .logout()
                .logoutSuccessUrl("/app/Index.jsp")
                .logoutRequestMatcher(new AntPathRequestMatcher("/reza"))
                .addLogoutHandler(ssoLogoutHandler);

和Zuul应用程序的SsoLogoutHandler类作为Spring-Security-OAuth2客户端:

@Component
public class SSOLogoutHandler implements LogoutHandler {
    @Override
    public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
        Object details = authentication.getDetails();

        String token = ((OAuth2AuthenticationDetails) details).getTokenValue();

        RestTemplate restTemplate = new RestTemplate();

        String url = "http://192.168.10.97:9191/uaa/token/revoke?token=" + token;

        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);

        ResponseEntity<Boolean> result = restTemplate.exchange(url, HttpMethod.GET, requestEntity, new ParameterizedTypeReference<Boolean>() {
        });
    }
}

和授权服务器的RevokeTokenController配置类:

@RestController
public class RevokeTokenController {

    @Autowired
    private TokenStore tokenStore;

    @RequestMapping(method = RequestMethod.GET, value = "/token/revoke")
    @ResponseBody
    public Boolean revoke(String token) throws Exception {
        OAuth2AccessToken tokenObj = tokenStore.readAccessToken(token);
        tokenStore.removeAccessToken(tokenObj);
        tokenStore.removeRefreshToken(tokenObj.getRefreshToken());
        return true;
    }


}

为了您看到的上述配置,客户端的SsoLogoutHandler调用restTemplate到Authorzation Server的RevokeTokenController注销,Token和Refresh Token被删除但客户端再次请求/ uaa / authorize ...获取新的访问令牌和日志出局不会发生。

哪里错了?我想在删除令牌和刷新令牌后注销,而不是再次获取访问令牌。另一只手我想在删除令牌后重定向到登录页面。

更新:

在删除令牌后我深入了解客户端请求,客户端请求像.../uaa/authorize?client_id=...,因此其响应的location属性是.../gateway/login?code=[code],因为代码,客户端没有重定向到登录页面。

答案

我建议在SSOLogoutHandler中移动令牌撤销逻辑,然后从那里重定向到登录页面,而不是调用单独的API调用。

因为如果由于API调用而无法执行令牌撤销逻辑,那么该令牌将在那里,您必须单独处理这些令牌,这将更加复杂。

在这种特殊情况下,如果TokenStore的autowire不起作用,则在其中一个配置文件中注册/创建SSOLogoutHandler的bean,并从那里为SSOLogoutHandler提供TokeStore依赖性。

另一答案

我已经通过Gateway和UAA中的两个注销端点解决了这个问题,首先,通过/logout端点,请求被重定向到Gateway以便注销,因此它自己的logoutSuccessUrl是UAA的/uaa/logout端点,以便这些端点,Gateway和UAA的注销都会发生。

像这样:

在网关

.and()
      .logout()
      .logoutSuccessUrl("/uaa/logout")
      .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));

而UAA配置的部分是:

.and()
      .logout()
      .logoutSuccessUrl("/login")
      .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));

以上是关于注销在Spring Security OAuth2中无法正常运行的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security Oauth2 removeAccessToken 不起作用

Spring Security 5 OAuth 2 社交注销

spring security + oauth2 + reactjs + restful http客户端

Spring Boot OAuth2 单点注销(注销)

Spring Boot + OAuth2 + Google Login - 如何实现注销

Spring Security 入门(1-3)Spring Security oauth2.0 指南