Выход из системы не работает правильно в Spring Security OAuth2 - PullRequest
0 голосов
/ 23 апреля 2019

В качестве клиента Spring-Security-OAuth2 и Сервера авторизации есть шлюз Zuul.Они расположены здесь

Часть конфигурации 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);

И класс SsoLogoutHandler приложения Zuul в качестве клиента 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 для RevokeTokenController сервера авторизации дляВыйти, Токен и Обновить токен удалены, но клиент снова запрашивает / uaa / authorize ..., чтобы получить новый токен доступа и выхода из системы не происходит .

В чем дело?Я хочу выйти из системы после удаления обоих токенов и обновить токен вместо того, чтобы снова получить токен доступа.С другой стороны, я хочу перенаправить на страницу входа после удаления токена.

Обновление:

Я был глубоко в клиентском запросе после удаления токена, клиент запрашивает как.../uaa/authorize?client_id=..., поэтому атрибут location его ответа равен .../gateway/login?code=[code], из-за кода клиент не перенаправляется на страницу входа.

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Я решил проблему двумя конечными точками выхода из системы как в шлюзе, так и в UAA. Таким образом, во-первых, конечной точкой /logout запрос перенаправляется в шлюз для выхода из системы, поэтому его собственная logoutSuccessUrl равна * 1003.* конечная точка UAA, для этих конечных точек происходит выход из шлюза и UAA.

, например:

В шлюзе

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

ичасть конфигурации UAA:

.and()
      .logout()
      .logoutSuccessUrl("/login")
      .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
0 голосов
/ 25 апреля 2019

Я бы предложил переместить логику отзыва вашего токена в SSOLogoutHandler, а затем перенаправить на страницу входа вместо вызова отдельного вызова API.

Потому что если что-то не в состоянии выполнить логику отзыва токена из-за вызова API, то этот токен будет там, и вам придется отдельно обрабатывать те токены, которые позже будут более сложными.

В этом конкретном случае, если autowire для TokenStore не работает, зарегистрируйте / создайте bean-компонент SSOLogoutHandler в одном из файлов конфигурации и предоставьте оттуда зависимость TokeStore для SSOLogoutHandler.

...