13

I am using Spring 4.0.5.RELEASE and Spring Security 3.2.4.

I am trying to create a simple sample app using java config (based on the Spring samples). The app starts up and the authentication works correctly, that is, I am redirected to a login form when accessing protected url /settings/profile

However there is no /logout url generated? if I hit localhost:8080/logout I get a 404.

I've used similar code on a previous project, so maybe has something to do with versions?

Heres my Security Config

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
        auth.inMemoryAuthentication().withUser("admin").password("password").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/settings/**").hasRole("ROLE_ADMIN")
                    .and()
                .formLogin()
                    .and()
                .logout()
                    .deleteCookies("remove")
                    .invalidateHttpSession(true)
                    .logoutUrl("/logout")
                    .logoutSuccessUrl("/logout-success")
                .permitAll();
    }
}

Here is my WebAppInitializer to bootstrap the app

 public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { SecurityConfig.class , MvcConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
         return new String[] {"/"};
    }
}

and finally my MvcConfig

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"web"})
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
Ayub Malik
  • 2,488
  • 6
  • 27
  • 42

1 Answers1

46

By default POST request is required to the logout url. To perform logout on GET request you need:

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

Or if you want to support PUT or other method, pass this as a parameter:

http
      .logout()
          .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "PUT"));

See the Docs: http://docs.spring.io/spring-security/site/docs/3.2.4.RELEASE/reference/htmlsingle/ (section 6.5.3. Logging Out)

Shubham A.
  • 2,446
  • 4
  • 36
  • 68
Evgeni Dimitrov
  • 21,976
  • 33
  • 120
  • 145
  • 4
    By any chance, do you know how to configure this with xml ? – yglodt May 11 '15 at 07:35
  • I am facing a similar problem. I am doing a POST /appContextRoot/logout and passing the necessary XSRF-TOKEN header, and I still get a 404. Is there more to it? – Kamal Joshi Nov 08 '15 at 04:28
  • 2
    Worth noting that this is not best practice, as it opens you up to potential CSRF attacks. From the JavaDoc: `The URL that triggers log out to occur (default is "/logout"). If CSRF protection is enabled (default), then the request must also be a POST. This means that by default POST "/logout" is required to trigger a log out. If CSRF protection is disabled, then any HTTP method is allowed. It is considered best practice to use an HTTP POST on any action that changes state (i.e. log out) to protect against CSRF attacks. ...` – Matthew Smith Jan 04 '16 at 20:22
  • in many cases, like in an old JSP, using a normal logout link will aways send a GET request, but you can use a form as a workaround like described here: https://stackoverflow.com/questions/6791238/send-post-request-on-click-of-href-in-jsp – Gregor Feb 01 '19 at 10:18
  • better yet, without JavaScript, but styling the button as a link: https://stackoverflow.com/a/22076149/160799 – Gregor Feb 01 '19 at 11:23