Reputation: 246
I use Spring security (4.0.2.RELEASE) to secure my app.
I can login just fine and my authenticated URLs are protected, but when I try to logout I constantly get 302 POST responses followed by a redirect to my configured failureUrl ("/cms/login?error").
Here's my WebSecurityConfig class
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/*").permitAll()
.antMatchers("/cms/*").authenticated()
.antMatchers("/cms/*/*").authenticated()
.antMatchers("/cms/*/*/*").authenticated().and()
.formLogin()
.loginPage("/cms/login")
.defaultSuccessUrl("/cms/login?success")
.failureUrl("/cms/login?error")
.permitAll().and()
.logout()
.logoutUrl("/cms/login?logout")
.logoutSuccessUrl("/cms/login")
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication()
.withUser("u")
.password("p")
.roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
}
Here's my login controller:
@Slf4j
@Controller
@RequestMapping(value = {"/cms", "/cms/login"})
public class CmsLoginController extends CmsBaseController
{
@RequestMapping
public ModelAndView handleLogin(HttpServletResponse request,
Model model,
@RequestParam(value = LOGIN_SUCCESS, required = false) String success,
@RequestParam(value = LOGIN_ERROR, required = false) String error,
@RequestParam(value = LOGOUT, required = false) String logout)
{
try
{
if (success != null)
{
setLoggedIn(true);
request.sendRedirect(XXXXX);
}
if (error != null)
{
model.addAttribute(LOGIN_ERROR, "Invalid username and password!");
}
if (logout != null)
{
model.addAttribute(LOGOUT, "You've been logged out successfully.");
setLoggedIn(false);
}
return new ModelAndView(CMS_CONTEXT + LOGIN_URL);
}
catch(Exception e)
{
setLoggedIn(false);
log.error(e.toString(), e);
return new ModelAndView(ERROR_VIEW_NAME);
}
}
}
For the record, I initially got the logout functionality working fine, but I must have introduced some change that has broken it unfortunately...
Any thoughts? Thank you
Upvotes: 5
Views: 4784
Reputation: 512
Unnecessary Logout logic done by spring for redirection Bothers me a little.
The default behavior should have been straight forward instead of the redirect, and they could have kept a provision for special cases.
Use the below in configure method
.logout().logoutUrl("/api/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
System.out.println("success");
}
});
Credits to this link https://www.codeproject.com/Tips/521847/Logout-Spring-s-LogoutFilter
Upvotes: 2
Reputation: 3423
I think the problem is the CSRF filter. In Spring Security 4 the CSRF prevention is turned on by default, do each POST request needs a CSRF token.
If you migrated your code from a previous Spring version then there is a very good chance that this is the problem.
For a quick test add http.csrf().disable
to your configuration. If it works that way then turn back the CSRF protection and add the CSRF token somehow into your POST logout request.
Upvotes: 0