Reputation: 681
We recently started using the @PreAuthorize
annotation with our REST endpoints. It works great, however, I did have a question regarding the HTTP code returned when issuing a GET vs. a POST or PUT.
It appears that when a user is not authorized to access the controller's REST endpoint that the HTTP status returned is different for GET and PUT/POST.
So for example, if I have an endpoint that is a GET and has a @PreAuthorize
annotation and the user doesn't have access, a 403 Forbidden is returned. This is what I expect.
If the same annotation is then placed on a controller method that is a POST or a PUT, the HTTP response is 405 Method Not Allowed (note that when properly authorized the POST/PUT method returns 200 as expected).
When stepping through the code you can see that the underlying security filter returns a 403, but in the POST/PUT scenario the status code is dropped/ignored and replaced with a 405, much like it does when a NullPointerExcpetion
occurs in your controller code.
Is this the expected behavior or should a 403 Forbidden always be returned for users who do not have access to an end point?
Upvotes: 11
Views: 4462
Reputation: 33
I solved this issue by allowing additional HTTP methods in my error controller, instead of allowing only GET requests:
public class MyErrorController implements ErrorController {
@RequestMapping(method = {
RequestMethod.GET,
RequestMethod.HEAD,
RequestMethod.POST,
RequestMethod.PUT,
RequestMethod.DELETE,
RequestMethod.OPTIONS,
RequestMethod.TRACE,
RequestMethod.PATCH})
public String displayError(){
// display error
}
}
My explanation:
Upvotes: 0
Reputation: 2585
For me the problem was inside the SecurityConfiguration
.
By removing the line .and().exceptionHandling().accessDeniedPage("/access-denied")
i got 403 Forbidden
instead of 405 Method not allowed
which is most probably what you would expect.
Upvotes: 2
Reputation: 588
It is possible that somewhere in between the request is being internally redirected and is ending up on a endpoint that is expecting a different HTTP request type and hence you are getting a HTTP 405. I have seen this has the most common reason in case of authentications
Upvotes: 0