我们正在使用 spring 和 spring-security-3.2。最近我们正在向 RestAPI 添加注释 @PreAuthorize(之前它是基于 URL 的)。
@PreAuthorize("hasPermission('salesorder','ViewSalesOrder')")
@RequestMapping(value = "/restapi/salesorders/", method = RequestMethod.GET)
public ModelAndView getSalesOrders(){}
我们已经有了用 - @ControllerAdvice 注释的全局异常处理程序和自定义 PermissionEvaluator,除了错误消息之外,一切正常。
假设某个用户正在访问 API,但没有“ViewSalesOrder”权限,那么 spring 默认会抛出异常“访问被拒绝”,但没有告诉缺少哪个权限(我们要求提及缺少哪个权限)。
是否可以抛出还包含权限名称的异常,因此最终的错误消息应类似于“访问被拒绝,您需要 ViewSalesOrder 权限”(此处权限名称应来自 @PreAuthorize 注释)?
请注意,我们有 100 个这样的 REST API,因此通用解决方案将受到高度赞赏。
没有很好的方法可以实现您的期望,因为PermissionEvaluator
接口不允许您将缺少的权限与评估结果一起传递。
此外,AccessDecisionManager
就股东大会的投票结果作出最终授权决定AccessDecisionVoter
实例,其中之一是PreInvocationAuthorizationAdviceVoter
就评估进行投票@PreAuthorize
value.
长话短说,PreInvocationAuthorizationAdviceVoter
当您的自定义PermissionEvaluator
回报false
to hasPermission
称呼。如您所见,无法传播此流程中的失败原因。
另一方面,您可以尝试一些解决方法来实现您想要的目标。
一种方法是在您的自定义中引发异常PermissionEvaluator
当权限检查失败时。您可以使用此异常将缺少的权限传播到全局异常处理程序。在那里,您可以将缺少的权限作为参数传递给消息描述符。请注意,这将停止执行过程AccessDecisionManager
这意味着连续的投票者不会被处决(默认是角色投票者 and 认证选民)。如果您选择走这条路,您应该小心。
另一种更安全但更笨拙的方法是实施自定义拒绝访问处理程序并在响应 403 之前自定义错误消息。AccessDeniedHandler
为您提供当前的HttpServletRequest
可用于检索请求 URI。然而,在这种情况下,坏消息是,您需要一个 URI 到权限映射才能找到丢失的权限。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)