Reputation: 1474
There are a Zuul gateway as Spring-Security-OAuth2 client and Authorization Server. Those are located here
The part of Zuul config:
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);
And the SsoLogoutHandler class of Zuul application as Spring-Security-OAuth2 client:
@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>() {
});
}
}
and the RevokeTokenController
config class of Authorization Server:
@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;
}
}
In order to above configuration that you see, SsoLogoutHandler
of client calls as restTemplate to RevokeTokenController
of Authorzation Server to log out, Token and Refresh Token are removed but the client again requests as /uaa/authorize... to get new access token and log out is not happen.
Where is wrong? I want to log out after removing both Token and Refresh Token instead of getting again the Access Token. Another hand I want to redirect to login page after removing the token.
Update:
I was deep into the client request after removing the token, the client requests like .../uaa/authorize?client_id=...
, so the location
attribute of its response is .../gateway/login?code=[code]
, because of the code, the client is not redirected to login page.
Upvotes: 0
Views: 1664
Reputation: 1474
I have solved the problem by two logout endpoints in both Gateway and UAA, in that way first, by the /logout
endpoint, the request is redirected to Gateway for logging out, so the its own logoutSuccessUrl
is /uaa/logout
endpoint of UAA, in order to these endpoints, both the logout of Gateway and UAA are happen.
like this:
In the Gateway
.and()
.logout()
.logoutSuccessUrl("/uaa/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
and the part of UAA config is:
.and()
.logout()
.logoutSuccessUrl("/login")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
Upvotes: 1
Reputation: 506
I would suggest to move your token revocation logic in SSOLogoutHandler and then redirect to login page from there instead of calling separate API call.
Because if something fails to execute token revocation logic due API call then that token will be there and you have to separately handle those tokens later on which will be more complex.
In this particular case, if autowire for TokenStore does not work then register/create a bean of SSOLogoutHandler in one of the connfiguration file and provide TokeStore dependancy from there for SSOLogoutHandler.
Upvotes: 0