'Spring security - Disable logout redirect

I'm using spring security with REST, and I'm using the URL (/logout) as an endpoint for my logout method. But after calling this method, it redirect me to (/login?logout), I know this is the spring logOutSuccessUrl. And I want to get rid of the redirection. This is my code:

protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
         .antMatchers("/login").permitAll()
         .anyRequest().fullyAuthenticated()
         .and().requiresChannel().anyRequest().requiresSecure()
         .and().httpBasic().disable().logout()
         .disable()
       //  .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
          .csrf().disable();

}

I tried to use HttpStatusReturningLogoutSuccessHandler but it didn't work, and even setting logoutSuccessUrl() doesn't change anything.

Do you know how can I disable this redirection?



Solution 1:[1]

Following code works for me (notice that it doesn't have logout().disable())

http.logout().permitAll();
http.logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));

Solution 2:[2]

So since there is no accepted answer yet, i post my solution, which worked for me:

.logout()
.logoutUrl("/api/user/logout")
.permitAll()
.logoutSuccessHandler((httpServletRequest, httpServletResponse, authentication) -> {
    httpServletResponse.setStatus(HttpServletResponse.SC_OK);
})
.and()

Just return a clean HTTP_OK (200) after successful logout - spring won't redirect you in this case

Solution 3:[3]

Foo those who use XML config, here is the equivalent snippet for the one given by Tahir Akhtar.

Within <http> element, configure the <logout> element as follows:

<logout
    logout-url          = "/some/path/for/logout"
    invalidate-session  = "true"
    delete-cookies      = "JSESSIONID"
    success-handler-ref = "httpStatusReturningLogoutSuccessHandler"
/>

And define httpStatusReturningLogoutSuccessHandler bean as follows:

<bean
    id      = "httpStatusReturningLogoutSuccessHandler"
    class   = "org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler"
/>

Solution 4:[4]

Use this method:

.logout().logoutSuccessUrl("enter address here where you want to go after logout")

Solution 5:[5]

You might want to try this

http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/thisistomisleadlogoutfilter"));

This effectively redirects /thisistomisleadlogoutfilter to login?logout. As such you should be able to use /logout instead

Solution 6:[6]

for logoutSuccessXXX() action, do not forget to add permitAll() since the cookie is cleared after the logout() method is called. So my sample solution is:

http
   ......
   .and()
       .logout()
           .logoutUrl("/logout")
           .logoutSuccessUrl("/logoutSuccess")
           **.permitAll()**

Solution 7:[7]

I used this:

    @ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping(value = "/oauth/revoke")
public void revokeToken(Authentication authentication) {
    ofNullable(authentication).ifPresent(auth -> {
        OAuth2AccessToken accessToken = tokenStore.getAccessToken((OAuth2Authentication) auth);

        ofNullable(accessToken).ifPresent(oAuth2AccessToken -> {
            ofNullable(oAuth2AccessToken.getRefreshToken()).ifPresent(tokenStore::removeRefreshToken);
            tokenStore.removeAccessToken(accessToken);
        });
    });
}

From this gist

Which worked perfectly. I recommend doing this over the logout() override primarily because it (well, it works, but other than that) preserves the oauth2 basic flow (/oauth/revoke) instead of using /logout or similar.

Hope that helps!

Solution 8:[8]

As of 2022, none of the answers above worked for me for different reasons (Using Spring Boot 2.6.6 + Thymeleaf).

Simplest solution that worked for me was implementing a POST form with a valid CSRF token in it. And rest of the default login/logout implementation provided by spring security just works out of the box.

So my web security config uses bare-bone defaults provided by spring-boot:

protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/resources/**").permitAll()
        .anyRequest()
        .fullyAuthenticated()
        .and().formLogin();
    }

and my template looks like (using BS5 dropdowns):

<ul class="dropdown-menu">
    <li><a class="dropdown-item" href="#">Settings</a></li>
    <li><a class="dropdown-item" href="#">Profile</a></li>
    <li>
        <form action="/logout" method="POST">
            <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
            <button class="dropdown-item" type="submit">Sign out</button>
        </form>
    </li>
</ul>

Please DON'T sacrifice the security (unless you have a valid reason for it) by disabling the CSRF token validation http.csrf().disable() just to be able to make GET /logout work without redirects, as recommended as solution by many neglectful articles around the web.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tahir Akhtar
Solution 2 Sebastian
Solution 3
Solution 4 Sergey Weiss
Solution 5 user3888170
Solution 6 f.khantsis
Solution 7 Kathryn Newbould
Solution 8 edigu