Reputation: 301
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?
Upvotes: 30
Views: 25117
Reputation: 718
In spring security 6.x if you want to have csrf only for some endpoints and your are doing the login/logout by your self, you can define it like that:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.ignoringRequestMatchers("/login",
"/logout",
"/instances",
"/instances/*",
"/actuator/**"))
.httpBasic(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.logout(AbstractHttpConfigurer::disable)
.build();
}
Upvotes: 0
Reputation: 1042
(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()
}
}
Upvotes: 0
Reputation: 10099
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.
Upvotes: 1
Reputation: 780
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()**
Upvotes: 1
Reputation: 63
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);
});
});
}
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!
Upvotes: 0
Reputation: 1671
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"
/>
Upvotes: 3
Reputation: 868
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
Upvotes: 28
Reputation: 11
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
Upvotes: 1
Reputation: 11625
Following code works for me (notice that it doesn't have logout().disable()
)
http.logout().permitAll();
http.logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
Upvotes: 53
Reputation: 1474
Use this method:
.logout().logoutSuccessUrl("enter address here where you want to go after logout")
Upvotes: 2