I know this is a bit late. I was having the same problem with /logout being rejected by my Angular2 browser app because of the CORS header Access-Control-Allow-Origin not being returned in the /logout response. The /logout seems to be processed before the CORS filter is reached so doesn't get the header. I tried the solution above but it didn't work for me. So, i tried this next solution and it works great:
- Create a LogoutHandler implementation class and implement logout()
- Create a LogoutSuccessHandler implementation class and implement onLogoutSuccess()
- Wire the two classes to the Spring security configuration
Turns out I didn't need the LogoutSuccessHandler class, just the LogoutHandler. The LogoutSuccessHandler (not shown) is just an empty implementation with a logging statement in it. The LogoutHandler is below. This is a snippet of a Spring-boot REST app coded in Groovy (very similar to java)
@Slf4j
class TodosLogoutHandler implements LogoutHandler {
/**
* For some reason the spring-session logout gets processed before the request
* reaches the CORS filter so the response doesn't get the allow-origin header
* which then causes the browser to reject the logout response. I tried a bunch
* of other methods of trying to include /logout to the CORS filter but they
* didn't work so figured a logout handler would be a place I could manually
* set the header to persuade the browser to accept the response - it worked!!
* @param request
* @param response
* @param authentication
*/
@Override
void logout(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) {
response.setHeader("Access-Control-Allow-Origin", "*")
log.info("TodosLogoutHandler logging you out of the back-end app.")
}
}
Then wire this together in your security configuration class that extends WebSecurityConfigurerAdapter like this below. The last part, showing the logout section is the relevant part in the standard configure() method.
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Allow any CORS OPTIONS calls
.antMatchers(HttpMethod.GET, "/priority", "/status").permitAll() // Allow all ref data
.anyRequest().authenticated()
.and()
.csrf().disable()
.httpBasic().realmName("Spring REST Todos")
.and()
// Custom logout handler only exists to handle a CORS problem with /logout
// where spring-session processes the logout request/response before it gets
// to the CORS filter so it doesn't get the allow-origin header which then
// causes the browser to reject the /logout response. Manually set the
// allow-origin header in the logout handler and Bob's your uncle.
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new TodosLogoutSuccessHandler())
.addLogoutHandler(new TodosLogoutHandler())
.invalidateHttpSession(true)
}