简体   繁体   中英

spring boot security using JSP as view engine logout does not work

Hi I'm trying to implement a spring boot web application using JSP as view engine. I'm following this tutorial as a basic: http://www.mkyong.com/spring-security/spring-security-hello-world-annotation-example/ I know that the tutorial didn't use spring boot. Anyway, I managed to implement a basic login thing. But the problem is that when I try to logout, it does not work and show me "White label error page" with the message saying "This application has no explicit mapping for /error, so you are seeing this as a fallback." and does not show any other specific messages.

Say for example, when I tried to login to "admin" page which is protected page. The login page appeared and I can successfully logged in. But when I clicked logout, the above error occurs and did not show any error on console as well. When I went to the previous url "/admin", it still showed that it was logged in with the previous user.

Since it doesn't show any error on console and on the web page, I have no clue to debug the issue. I'm very new to Spring web application, so please explain me what's wrong and how to fix the issue.

This is my main Application.java file

@ComponentScan
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {
    private static final Logger LOGGER = LoggerFactory.getLogger(Application.class.getName());

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        LOGGER.info("Starting Main Application...");
        SpringApplication.run(Application.class, args);
        LOGGER.info("Access URLs: http://127.0.0.1:8080\n");
    }

}

This is my application.properties file

spring.mvc.view.prefix= /WEB-INF/jsp/
spring.mvc.view.suffix= .jsp

This is my SecurityConfig.java file

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").access("hasRole('ADMIN')")
            .antMatchers("/user/**").access("hasRole('ADMIN') or hasRole('USER')")
            .antMatchers("/index").permitAll()
            .antMatchers("/").permitAll()
        .and()
            .formLogin()
        .and()
            .logout()
            .logoutSuccessUrl("/");
    }
}

This is my MainController.java

@Controller
public class MainController {
    private static final Logger LOGGER = LoggerFactory.getLogger(MainController.class);

    @RequestMapping({"/index", "/"})
    public String index(Model model) {
        model.addAttribute("title", "Spring Web Application example");
        model.addAttribute("message", " This is Spring Web Application example using Spring boot, JSP");
        LOGGER.debug("Inside MainController.index() method");
        return "index";
    }

    @RequestMapping(value = "/admin**", method = RequestMethod.GET)
    public String adminPage(Model model) {
        model.addAttribute("title", "Spring Security Web Application example");
        model.addAttribute("message", "This is a protected page");
        model.addAttribute("h2", "only user with ADMIN role should be able to access this page!");
        return "admin";
    }

    @RequestMapping(value = "/user**", method = RequestMethod.GET)
    public String userPage(Model model) {
        model.addAttribute("title", "Spring Security Web Application example");
        model.addAttribute("message", "This is a protected page");
        model.addAttribute("h2", "only user with either USER or ADMIN role should be able to access this page!");
        return "user";
    }

}

I excluded the jsp files and pom file, if you would like to see the whole project, please have a look at my github repository https://github.com/agthumoe/spring-boot-security

Thanks

As said in documentation , by default CSRF protection is enabled. That means, /logaout will be accessible only for post request. And post request has to include CSRF Token. So, you can do something like following:

<form action="/logout" method="post">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    <input type="submit" value="Log out" />
</form>

This form is just example. Of course you can remove button and submit it with javascript, by clicking the link.

As another solution, you can disable CSRF protection (not a good idea in terms of security):

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    ....

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
            .csrf().disable()
            .authorizeRequests()
            ....;        
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM