Piotr Żak
Piotr Żak

Reputation: 2403

Spring Security blocking Rest Controller

My app has Spring boot 1.3.2 and I'm trying use Spring MVC with Spring Security.

I have administration panel under http://localhost:8080/admin and my page content for common users under http://localhost:8080/

If You are trying to open an admin panel (http://localhost:8080/admin) You have to log in, if You are common just enter http://localhost:8080/ and have fun no log in required.

My Security config class:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/**").permitAll()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/login");
    }

}

Config above let me to require login from /admin But I have some problem with Admin panel features.

This is Controller I'm trying to request with POST from admin panel:

@RestController
@RequestMapping("/admin/v1")
public class AdminController {

    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        String hello = "hi!";
        return hello;
    }
}

So I can log in, browser render Admin panel for me but when I'm clicking logout button which request POST logout method from Controller above. App tells me 403 Forbidden

Can anybody tell me what I'm doing wrong?

Upvotes: 3

Views: 1793

Answers (1)

Shaheer
Shaheer

Reputation: 1643

Most probably the 403 Forbidden error is because the spring by default enable csrf protection. You can disable csrf in configuration or Include the CSRF Token in the POST method.

Disable csrf in config:

http
    .csrf().disable()
    .authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .antMatchers("/**").permitAll() 
        .anyRequest().permitAll()
            .and()
            .formLogin()
            .loginPage("/login")                     
        .and()
        .logout()
        .logoutSuccessUrl("/admin/v1/logout");

Include the CSRF Token in Form Submissions:

<c:url var="logoutUrl" value="/admin/v1/logout"/>
<form action="${logoutUrl}" method="post">
<input type="submit" value="Log out" />

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>

Upvotes: 1

Related Questions