Spring security - Disable logout redirect
Asked Answered
D

9

28

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?

Drosophila answered 1/4, 2016 at 10:49 Comment(1)
This article details how to disable the logout redirect: baeldung.com/spring-security-disable-logout-redirectsOckeghem
K
51

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

http.logout().permitAll();
http.logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
Kemp answered 2/4, 2016 at 13:32 Comment(4)
Try setting logging level of spring security to debug, it might give you a hint. If using spring boot, you can add logging.level.org.springframework.security=DEBUG to application.propertiesKemp
@Drosophila Did you get it to work? I am having the similar issue. Tried all solutions, nothing works.Directed
I'm using spring-security 4.2.0.RELEASE with XML config and it works.Clarettaclarette
We don't need to pass OK explicitly it is the default value.Opportuna
P
27

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

Predetermine answered 5/7, 2017 at 8:10 Comment(1)
Dude, you made my day. Many thanks, this should be the accepted answer.Virility
C
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"
/>
Clarettaclarette answered 10/5, 2017 at 17:42 Comment(0)
S
2

Use this method:

.logout().logoutSuccessUrl("enter address here where you want to go after logout")
Scamander answered 1/4, 2016 at 11:8 Comment(3)
OP wants to get rid of the redirect as the /logout is being called from a REST client (probably AJAX requests from a browser)Kemp
The question was to disable the redirect, not to change it to a different url.Pulp
This may not have solved the OP problem but it solved mine. This was making it go in a loop, along with the 'access="permitAll"'. Thank you!Kaplan
E
1

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

Ellanellard answered 22/5, 2017 at 14:53 Comment(0)
D
1

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()**
Duo answered 15/4, 2019 at 2:54 Comment(0)
F
1

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.

Fortitude answered 25/4, 2022 at 11:19 Comment(0)
S
0

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!

Scientific answered 26/11, 2019 at 8:32 Comment(0)
M
0

(Kotlin) On Spring security 6, You can just disable it like this:

@Configuration
class SecurityConfig(
    private val jwtAuthFilter: JwtAuthFilter,
    private val authenticationProvider: AuthenticationProvider
) {

    @Bean
    @Throws(Exception::class)
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain? {
        return http
            .csrf { it.disable() }
            .cors(Customizer.withDefaults())
            .authorizeHttpRequests {
                it.requestMatchers("/auth/**", "/api-docs/**", "swagger-ui/**")
                    .permitAll()
                    .anyRequest()
                    .authenticated()
            }
            .sessionManagement { session ->
                session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            }
            .formLogin { it.disable()} // <-- Disable form login
            .logout { it.disable() } // <-- Disable logout redirect
            .authenticationProvider(authenticationProvider)
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter::class.java)
            .build()
    }
}
Mary answered 21/5, 2024 at 14:54 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.