【问题标题】:Spring Security ACL - create permissionSpring Security ACL - 创建权限
【发布时间】:2013-04-17 18:50:21
【问题描述】:

我可以使用带有实体权限的 Spring Security ACL,但我想知道如何测试用户是否有权访问类的“创建”(位 2)权限。

类似:

aclPermissionEvaluator.hasPermission(auth, clazz, "create")

有人可以帮我吗?

提前致谢

【问题讨论】:

    标签: spring-security acl


    【解决方案1】:

    我有完全相同的问题,遗憾的是,没有“开箱即用”的解决方案。

    如果您的域模型允许,一种方法是将创建权限添加到您要创建的父对象

    例如,假设您想为客户创建一个用户。您可以为允许为此特定客户端创建用户的用户添加创建权限到客户端。那就是我选择的路径。

    如果您的域对象不允许这样做,我发现这样做的唯一方法是:

    • 创建一个新表acl_class_entry,列表acl_entry等价但链接到acl_class而不是acl_object_identity
    • 然后你创建你自己的权限评估器,如果target_id 为空,附加方法boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) 来检查acl_class_entry 的权限。这将允许您使用 SPel 表达式 hasPermission(nulll, 'className', 'permission') 检查对类的权限
    • 当然,您还需要创建自己的AclService 版本来创建此类权限。

    【讨论】:

      【解决方案2】:

      您可以使用 Spring 的 SpEL 注释,例如@PreAuthorize,并覆盖PermissionEvaluator接口的hasPermission方法。如果您使用按位权限掩码,并且用户的权限(作为int)评估为“15”(1111),并且对象所需的权限是“6”(0110),您可以执行以下操作:

      public boolean hasPermission(Authentication auth, Object targetObject, Object requiredPermissions) {
          int permissionMask = MyUserClass.getMask();
          int permissionsRequired = Integer.valueOf(requiredPermissions.toString());
          return ((permissionMask | requiredPermissions) == permissionMask);
      }
      

      只要对象权限掩码中的活动位在用户权限上处于活动状态,这将返回 true。然后,您需要在 security.xml 文件中声明此自定义权限评估器:

      <security:global-method-security pre-post-annotations="enabled">
          <security:expression-handler ref="expressionHandler"/>
      </security:global-method-security>
      
      <bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
          <property name="permissionEvaluator" ref="permissionEvaluator"/>
      </bean>
      
      <bean id="permissionEvaluator" class="my.project.package.CustomPermissionEvaluator"/>
      

      现在,无论您何时致电 hasPermission(),您的自定义评估程序都会处理该请求。显然,您可以使用您喜欢的任何逻辑来评估权限——只要确保返回类型为boolean,并且要传递的参数与您发送的参数相匹配(或评估的对象;注意格式异常)。

      请注意,您的自定义参数必须作为Object 传递以覆盖hasPermission();您还可以通过更改签名来重载该方法以处理您喜欢的任何参数类型(例如 String 或 int),并且编译器应该选择最具体的签名。但是,由于您正在实现 PermissionEvaluator 接口,因此无论如何您都必须包含给定的签名(身份验证、对象、对象),因此除非您有特定需要编写重载方法,否则您也可以直接覆盖。

      【讨论】:

      • 嗨@cabbagery,感谢您的回答,但它仍然没有寻找特定课程的许可......
      • 您是在谈论类级别的注释驱动访问,还是在谈论 ACL(acl_class 表)中的对象?另外,如果您还没有搜索过它,请查看Mark Serrano's ACL tutorial。我将他的一些教程与其他资源和我自己的一些实验结合使用,发现它非常有帮助。
      猜你喜欢
      • 2014-05-11
      • 2013-11-07
      • 2011-09-02
      • 2011-11-20
      • 2014-02-18
      • 2014-11-16
      • 1970-01-01
      • 2013-02-25
      相关资源
      最近更新 更多