使用@Preauthorize和@@ ControllerAdvice的自定义错误消息 [英] Custom Error message with @Preauthorize and @@ControllerAdvice

查看:63
本文介绍了使用@Preauthorize和@@ ControllerAdvice的自定义错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用spring和spring-security-3.2.最近,我们在RestAPIs中添加了@PreAuthorize注释(以前是基于URL的.)

We are using spring and spring-security-3.2. Recently We are adding annotations @PreAuthorize to RestAPIs(earlier it was URL based).

     @PreAuthorize("hasPermission('salesorder','ViewSalesOrder')")
  @RequestMapping(value = "/restapi/salesorders/", method = RequestMethod.GET)
  public ModelAndView getSalesOrders(){}

我们已经有了全局异常处理程序,该处理程序带有-@ControllerAdvice和自定义的PermissionEvaluator注释,除错误消息外,其他所有功能都正常.

We already have Global exception handler which annotated with - @ControllerAdvice and custom PermissionEvaluator in place, everything works fine except the error message.

让我们说一些用户正在访问API,此刻,在没有"ViewSalesOrder"权限的情况下,默认情况下,spring会抛出异常访问被拒绝",但并没有告诉您缺少哪个权限(这是我们要求提到的哪个权限丢失的要求).

Lets say some user is accessing API At moment without having 'ViewSalesOrder' permission then spring by default throws the exception 'Access is denied',but didn't tell which permission is missing (Its our requirement to mention which permission is missing).

是否有可能引发包含权限名称的异常,因此最终错误消息应类似于访问被拒绝,您需要ViewSalesOrder权限"(此处的权限名称应来自@PreAuthorize批注)?

Is it possible to throw an exception which also include the permission name, so final error message should be look like "Access is denied, you need ViewSalesOrder permission"(here permission name should be from @PreAuthorize annotation)?

请注意,我们已经有100个这样的restAPI,因此高度赞赏通用解决方案.

Please note that we have 100 such restAPI in place so generic solution will be highly appreciated.

推荐答案

由于 PermissionEvaluator 接口不允许您将缺少的权限与结果一起传递,因此没有实现您期望的漂亮方法评估的结果.
另外, AccessDecisionManager 决定关于 AccessDecisionVoter 实例投票的最终授权,其中之一是 PreInvocationAuthorizationAdviceVoter @PreAuthorize 值的评估.

长话短说,当您的自定义 PermissionEvaluator 返回 false hasPermission 调用.如您所见,没有办法在此流程中传播失败的原因.

There is no pretty way of achieving what you expect since PermissionEvaluator interface doesn't let you pass the missing permission along with the result of the evaluation.
In addition, AccessDecisionManager decides on the final authorization with respect to the votes of the AccessDecisionVoter instances, one of which is PreInvocationAuthorizationAdviceVoter which votes with respect to the evaluation of @PreAuthorize value.

Long story short, PreInvocationAuthorizationAdviceVoter votes against the request (giving the request –1 point) when your custom PermissionEvaluator returns false to hasPermission call. As you see there is no way to propagate the cause of the failure in this flow.

另一方面,您可以尝试一些变通办法来实现所需的目标.

一种方法是当权限检查失败时,在自定义的 PermissionEvaluator 中引发异常.您可以使用此异常将缺少的权限传播到全局异常处理程序.在那里,您可以将缺少的权限作为参数传递给消息描述符.请注意,这将暂停 AccessDecisionManager 的执行过程,这意味着将不执行连续的投票者(默认值为

On the other hand, you may try some workarounds to achieve what you want.

One way can be to throw an exception within your custom PermissionEvaluator when permission check fails. You can use this exception to propagate the missing permission to your global exception handler. There, you can pass the missing permission to your message descriptors as a parameter. Beware that this will halt execution process of AccessDecisionManager which means successive voters will not be executed (defaults are RoleVoter and AuthenticatedVoter). You should be careful if you choose to go down this path.

Another safer but clumsier way can be to implement a custom AccessDeniedHandler and customize the error message before responding with 403. AccessDeniedHandler provides you current HttpServletRequest which can be used to retrieve the request URI. However, bad news in this case is, you need a URI to permission mapping in order to locate the missing permission.

这篇关于使用@Preauthorize和@@ ControllerAdvice的自定义错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆