使用@PreAuthorize时,从Spring Controllers返回405 vs 403

时间:2014-06-09 13:19:41

标签: rest spring-security annotations

我们最近开始在我们的REST端点上使用@PreAuthorize注释。它工作得很好,但是,我确实对发出GET与POST或PUT时返回的HTTP代码有疑问。 似乎当用户未被授权访问控制器的REST端点时,返回的HTTP状态对于GET和PUT / POST是不同的。

因此,例如,如果我的端点是GET并且具有@PreAuthorize注释且用户没有访问权限,则返回403 Forbidden。这就是我的期望。

如果然后将相同的注释放在POST或PUT的控制器方法上,则HTTP响应为405 Method Not Allowed(请注意,正确授权POST / PUT方法按预期返回200)。

当单步执行代码时,您可以看到底层安全过滤器返回403,但在POST / PUT场景中,状态代码被删除/忽略并替换为405,就像{{1}时的情况一样。 }出现在您的控制器代码中。

这是预期的行为还是应该为无法访问终点的用户返回403 Forbidden?

3 个答案:

答案 0 :(得分:1)

对我来说,问题出在SecurityConfiguration内部。

通过删除行.and().exceptionHandling().accessDeniedPage("/access-denied"),我得到了403 Forbidden而不是405 Method not allowed,这很可能是您期望的。

答案 1 :(得分:0)

请求之间的某个位置可能在内部重定向,并且最终会出现在期望不同HTTP请求类型的端点上,因此您将获得HTTP 405。 我已经看到这是认证的最常见原因

答案 2 :(得分:0)

我通过在错误控制器中允许其他HTTP方法而不是仅允许GET请求来解决此问题:

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
    }
}

我的解释:

  1. 所请求的资源允许使用POST方法,但是由于无效的身份验证或授权,SpringSecurity拒绝了该请求。
  2. SpringSecurity在内部重定向到错误控制器以显示HTTP 403的错误页面。此处使用初始请求中的HTTP方法,即POST。
  3. 错误控制器仅允许GET请求,这就是为什么返回HTTP 405的原因。