【问题标题】:Is it possible to prefetch database object from auth/custom annotation in Spring boot是否可以在 Spring Boot 中从 auth/custom 注释中预取数据库对象
【发布时间】:2022-10-23 19:45:20
【问题描述】:

我的 Spring MVC 控制器中有以下端点:

@RestController
public class ToolsController {

    @GetMapping("/v1/auth-check/....id....")
    @RolesAllowed(...)
    @MyCustomPermissions(...)
    public MyResult checkAuth(...., int databaseId, ....) {

这里的角色允许是一个标准注释,它检查用户数据并防止在没有权限的情况下调用方法。

现在我还想借助包含在由参数databaseId 标识的数据库对象中的数据来检查权限。我可以从某处读取此对象,以便我的注释也阻止调用方法吗?

我可以在HandlerInterceptorAdapter#preHandle 中单独解析请求

这很糟糕,因为我将复制 Spring 的工作。还有其他机制吗?

【问题讨论】:

    标签: java spring spring-security interceptor


    【解决方案1】:

    使用@PreAuthorize,它允许您定义一个SpEL 来引用任何bean 中的方法,该方法将在调用方法进行权限检查之前执行。权限检查方法应该返回一个布尔值,true 表示允许,false 表示不允许。

    在该 SpEL 中,您可以使用 @bean 引用 bean 并使用 #foo@P 访问 @PreAuthorize 保护的方法的参数。(here 上的文档)

    就像是 :

    @GetMapping("/v1/auth-check/....id....")
    @PreAuthorize("@authzService.isAllow(#databaseId)")
    public MyResult checkAuth(...., int databaseId, ....) {
    
    }
    

    它将查找名称为authzService 的bean 并执行其isAllow() 以进行权限检查。

    @Service
    public class AuthzService{
    
        public boolean isAllow(int databaseId){
            /******************************************
              Do the checking here....
              Use SecurityContextHolder.getContext().getAuthentication() to access the current user object such that you can check their roles. 
             ******************************************/
        }
    } 
    

    【讨论】:

      【解决方案2】:

      如果您所指的对象“数据库对象”checkAuth() 返回的结果,那么您肯定可以检查它的内容@PostAuthorize。如果作为参数提供的 SpEl 表达式不匹配,则请求处理将失败并出现异常。

      它看起来像这样:

      @PostAuthorize("returnObject.databaseId ... <- your-conditional-logic-here")
      

      提醒:要启用此注释,@EnableGlobalMethodSecurityprePostEnabled 属性(注释配置类) 需要设置为true (我想你知道这一点,但随机读者可能不会):

      @EnableGlobalMethodSecurity(prePostEnabled=true)
      

      如果您没有引用结果对象,那么您可以检索它“数据库对象”就在 SpEl 表达式中,因为我们可以自由地使用任何 Bean 并调用它们的方法。所以它仍然可以使用@PostAuthorize

      另外,值得注意的是:

      • 最好保持 SpEl 表达式尽可能简单,因为它很难测试。
      • HandlerInterceptorAdapter 自发布版本5.3 以来已弃用,因此它不是一个很好的选择。

      【讨论】:

        猜你喜欢
        • 2014-05-21
        • 2019-03-28
        • 2020-03-09
        • 2018-05-24
        • 2022-06-24
        • 2019-10-27
        • 2011-02-19
        • 2021-11-30
        • 1970-01-01
        相关资源
        最近更新 更多