HTTP 405 Not Allowed - Spring Boot + Spring Security

走远了吗. 提交于 2019-12-31 04:00:27

问题


I have a simple rest API which works with database. It worked properly until I added the security part. Now it gives HTTP 405 Not Allowed on the POST and DELETE requests. I have no idea why. The GET requests work properly.

So here is the controller class:

@Controller
public class MarkerController {

    private Logger logger = Logger.getLogger(MarkerController.class.getName());

    @Autowired
    private MarkerServiceInterface markerService;

    @RequestMapping(value="/markers", method=RequestMethod.GET)
    public @ResponseBody List<Marker> getMarkers(@RequestParam(value="city", defaultValue="") String city) {
        logger.info("HANDLE GET REQUEST");



        return this.markerService.getAllMarkers();
    }

    @RequestMapping(value="/markers/new", method=RequestMethod.POST)
    public @ResponseBody Marker addMarker(@RequestBody Marker marker) {
        logger.info("HANDLE POST REQUEST");

        this.markerService.addMarker(marker);
        return marker;
    }

    @RequestMapping(value="/markers/delete", method=RequestMethod.DELETE)
    public @ResponseBody String deleteMarker(@RequestParam(value="id", defaultValue="") String id) {
        logger.info("HANDLE DELETE REQUEST");
        if (!id.equals("")) {
            logger.info(id);
            this.markerService.deleteMarker(Long.parseLong(id));
        }
        return "";
    }

    @RequestMapping(value="/admin/map")
    public String trafficSpy() {
        logger.info("HANDLE MAP");
        return "index";
    }

    @RequestMapping(value="/admin")
    public String admin() {
        return "admin";
    }

    @RequestMapping(value="/login")
    public String login() {
        return "login";
    }

}

This is the SecurityConfig:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("userDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(
                passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http    
            .authorizeRequests()
            .antMatchers("/admin/**")
            .access("hasRole('ROLE_ADMIN')")
            .antMatchers("/markers/**")
            .access("hasRole('ROLE_USER')")
            .and()
            .formLogin()
            .loginPage("/login")
            .failureUrl("/login?error")
            .usernameParameter("username")
            .passwordParameter("password")
            .and()
            .logout()
            .logoutSuccessUrl("/login?logout")
            .and()
            .csrf()
            .and()
            .exceptionHandling()
            .accessDeniedPage("/403");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    @Bean
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }
}

The DELETE request is called with the following ajax code:

$.ajax({
        url: "localhost:8080/markers/delete?id=" + currentMarker.get("id"),
        type: 'DELETE',
        success: function(result) {
            console.log(result);
        }
    });

And here is the message given in the console:

2015-05-11 15:48:13.671  WARN 8279 --- [nio-8181-exec-6] o.s.web.servlet.PageNotFound             : Request method 'DELETE' not supported

These are the headers of the response. I can see that in AlLLOW I have only GET and HEAD. So if I'm right, this means that the method in the controller accepts only GET and HEAD requests.

(Status-Line)               HTTP/1.1 405 Method Not Allowed
Server                      Apache-Coyote/1.1
x-content-type-options      nosniff
x-xss-protection            1; mode=block
Cache-Control               no-cache, no-store, max-age=0, must-revalidate
Pragma                      no-cache
Expires                     0
X-Frame-Options             DENY
Allow                       GET, HEAD
Content-Type                application/json;charset=UTF-8
Transfer-Encoding           chunked
Date                        Mon, 11 May 2015 17:35:31 GMT

In the response I have this exeption:

org.springframework.web.HttpRequestMethodNotSupportedException

Any idea what is causing this problem? How can I allow the POST and DELETE methods?


回答1:


You forget the csrf-Token.

It's recommended that you add the csrf-Token in the meta-tag. You can read it in the Spring Security Documentation

With this you can do the following:

$(function () {
  var token = $("meta[name='_csrf']").attr("content");
  var header = $("meta[name='_csrf_header']").attr("content");
  $(document).ajaxSend(function(e, xhr, options) {
    xhr.setRequestHeader(header, token);
  });
});



回答2:


I wanted to leave an additional solution, because although Manu Zi's answer is a correct one, it wasn't immediately clear to me why the first time I came across this issue and found this answer.

The underlying issue was obscured by the immediate problem of the 405 Method Not Allowed.

In my case, there were two factors at play. Firstly, there was no POST method for my AccessDenied controller, which resulted in a 405 when a POST method was denied and redirected to the AccessDenied controller. This was only evident after turning up debug logging on org.springframework.web.

Once that was clear, it was a matter of figuring out why I was getting access denied. All the permissions and roles were correct, but having upgraded from Spring 3 to 4, I found that CSRF protection was enabled by default. It either needs to be disabled, or you have to use Manu Zi's solution.

To disable it, see: spring security 4 csrf disable via xml



来源:https://stackoverflow.com/questions/30171265/http-405-not-allowed-spring-boot-spring-security

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!