1

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

就像是 :

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

有人可以帮助我吗?

提前致谢

4

2 回答 2

0

您可以使用 Spring 的 SpEL 注释,例如@PreAuthorize,并覆盖接口的hasPermission方法PermissionEvaluator。如果您使用按位权限掩码,并且用户的权限(作为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 接口,因此无论如何您都必须包含给定的签名(身份验证、对象、对象),因此除非您有某些特定需要编写重载方法,否则您也可以直接覆盖。

于 2013-04-24T17:57:51.280 回答
0

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

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

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

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

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