我们最近开始在我们的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?
答案 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
}
}
我的解释: