如何在 Spring Security 3.1 中使用 acl_entry 表中的掩码字段? [英] How do i use the mask field in acl_entry table in Spring Security 3.1?

查看:35
本文介绍了如何在 Spring Security 3.1 中使用 acl_entry 表中的掩码字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Spring Security 3.1 ACL 实现.因此,根据教程,我创建了一个包含下表的 acl 数据库:

I use the Spring Security 3.1 ACL implementation. So based on a tutorial i have created a acl databse with the following tables:

CREATE TABLE IF NOT EXISTS `acl_class` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `class` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_2` (`class`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `acl_entry` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `acl_object_identity` bigint(20) NOT NULL,
  `ace_order` int(11) NOT NULL,
  `sid` bigint(20) NOT NULL,
  `mask` int(11) NOT NULL,
  `granting` tinyint(1) NOT NULL,
  `audit_success` tinyint(1) NOT NULL,
  `audit_failure` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_4` (`acl_object_identity`,`ace_order`),
  KEY `foreign_fk_5` (`sid`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `acl_object_identity` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `object_id_class` bigint(20) NOT NULL,
  `object_id_identity` bigint(20) NOT NULL,
  `parent_object` bigint(20) DEFAULT NULL,
  `owner_sid` bigint(20) DEFAULT NULL,
  `entries_inheriting` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_3` (`object_id_class`,`object_id_identity`),
  KEY `foreign_fk_1` (`parent_object`),
  KEY `foreign_fk_3` (`owner_sid`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `acl_sid` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `principal` tinyint(1) NOT NULL,
  `sid` varchar(100) NOT NULL,
  `password` varchar(255) NOT NULL,
  `salt` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

这适用于注释,例如:

@PreAuthorize("hasPermission(#element, 'WRITE')")
@PostAuthorize("hasPermission(returnObject, 'READ')")

读取"和写入"权限在表 acl_entry 中设置为字段掩码.据我了解,1 表示读取",2 表示写入",4 表示创建",8 表示删除",16 表示管理",因为它似乎是一种按位身份验证方法.

The rights "Read" and "Write" are set in the table acl_entry to the field mask. As i understood 1 means "READ", 2 means "Write", 4 means "Create", 8 means "Delete" and 16 means "Administer", because it seems to be a bitwise authentication method.

  1. 问题:我是否正确理解了权利的授予?
  2. 问题:如何指定读/写"等组合权限?我可以设置"位 0(即 int 1)和 1(即 int 2),以便得到掩码值 1+2=3?

现在我必须为读取"和写入"权限创建单个条目,这不太方便.

Now i have to create single entries for the "READ" and "Write" permission, that's not pretty handy.

推荐答案

根据 PacktPub 的 Spring Security 3.1:

不幸的是,AclImpl 的实际实现直接比较了我们的 [@PostFilter] 注释中 SpEL 表达式中指定的权限,以及存储在 ACE 中的权限数据库,不使用按位逻辑.Spring Security 社区正在争论这是无意的还是按预期工作的...
Unfortunately, the actual implementation of AclImpl directly compares the permission specified in our SpEL expression in our [@PostFilter] annotation, and the permission stored on the ACE in the database, without using bitwise logic. The Spring Security community is in debate about whether this is unintentional or working as intended. . .

那本书中的示例试图完全按照您的描述去做——它指定了一个角色为 3 的用户,用于读/写,但是用户被拒绝访问权限掩码为 1 的对象,用于读取.

The example in that book tries to do exactly what you're describing -- it specifies a user with a role of 3 for read/write, but the user is denied access to an object with a permission mask of 1 for read.

解决方案是编写您自己的自定义权限评估器.

The solution is to write your own custom permission evaluator.

MyPermissionEvaluator.java:

public class MyPermissionEvaluator implements PermissionEvaluator {

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object requiredPermissions) {
        //some way to access your user's assigned permission mask
        int permissionMask = MyUserDetails.getMask();

        //the requiredPermissions object must be cast as a String, and then
        //converted to an integer, even though it is an integer in the ACL table
        int permissionsRequired = Integer.valueOf(requiredPermissions.toString());

        //a simple bitwise OR will identify whether the user has the required permissions
        return ((permissionMask | permissionsRequired) == permissionMask);
    }

    . . .

}

要实际使用此自定义权限评估器,请编辑您的 security.xml 文件:

To actually use this custom permission evaluator, edit your security.xml file:

<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

<bean id="espressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>

<bean id="permissionEvaluator" class="my.project.package.MyPermissionEvaluator"/>

最后,每当一个方法或类需要一定的权限级别时:

Finally, whenever a method or class requires a certain permission level:

@PreAuthorize("hasPermission(#this, '4')")
public void mySecuredMethod() { //some secured method
}

现在您可以将 ACL 表中的权限掩码设置为与您的组织需求(按位)相对应的任何内容,并以您识别每个用户的权限的任何方式执行相同操作.例如,

Now you can set the permission mask in the ACL table to whatever corresponds to your organizational needs (bitwise), and do the same in whatever way you identify each individual user's permissions. For example,

user    site_admin_bit    database_admin_bit    edit_data_bit    write_data_bit    read_data_bit
nancy        0                   1                   1                 0                1

因此,Nancy 的权限掩码为 13(可能是 31),存储在您的用户详细信息实现中.如果她尝试访问权限要求为 edit_data 的对象,她的权限将根据掩码要求 4 和按位 OR 评估(permissionMask| permissionRequired == permissionMask) 将评估为 true.

Nancy thus has a permission mask of 13 (out of a possible 31) as stored in your user details implementation. If she tries to access an object with a permission requirement of edit_data, her permissions would be checked against a mask requirement of 4, and a bitwise OR evaluation (permissionMask | permissionsRequired == permissionMask) would evaluate to true.

在我看来,这是实现特定于组织的按位权限掩码的最简单方法(我认为可以使用 32 位,这应该足够了).根据参考书,Spring注解中使用的hasPermissionSpEL表达式将用户的权限作为一个完整的单元进行评估;如果用户在 3 处设置了读/写权限,但注释仅针对 read (1) 进行评估,则用户将拒绝访问.

This is, in my estimation, the easiest way to implement an organization-specific bitwise permissions mask (with 32 bits to play with, which should be enough, I should think). According to the referenced book, the hasPermission SpEL expression used in Spring annotations evaluates the user's permissions as a complete unit; if the user has a permission set at 3 for read/write, but the annotation only evaluates against read (1), the user will be denied access.

这篇关于如何在 Spring Security 3.1 中使用 acl_entry 表中的掩码字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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