【问题标题】:Log Out does not work correctly in Spring Security OAuth2注销在 Spring Security OAuth2 中无法正常工作
【发布时间】:2019-09-12 11:09:24
【问题描述】:

有一个 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 config 类:

@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注销,令牌和刷新令牌被删除但客户端再次请求为/uaa/authorize ... 获取新的访问令牌并注销不会发生

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

更新:

我在去掉token后深入到客户端请求,客户端请求像.../uaa/authorize?client_id=...,所以它响应的location属性是.../gateway/login?code=[code],因为代码,客户端未重定向到登录页面。

【问题讨论】:

    标签: spring-boot oauth-2.0 microservices spring-security-oauth2


    【解决方案1】:

    我已经通过网关和 UAA 中的两个注销端点解决了这个问题,首先,通过/logout 端点,请求被重定向到网关进行注销,所以它自己的logoutSuccessUrl 是@987654323 @UAA的端点,为了这些端点,网关和UAA的注销都会发生。

    像这样:

    在网关中

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

    UAA 配置的部分是:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 我已更改为 login-page-uri 但再次获得新的访问令牌而不是 login-page
      • @rezaramezanimatin 您是否已将撤销逻辑移至注销处理程序?成功了吗?
      • 是的,它不起作用。问题是在注销处理程序之后,客户端再次能够从 UAA 获取新的访问令牌
      猜你喜欢
      • 2018-10-29
      • 2017-04-29
      • 1970-01-01
      • 2020-02-09
      • 2021-09-20
      • 2013-05-06
      • 1970-01-01
      • 2018-09-02
      • 2011-06-28
      相关资源
      最近更新 更多