spring security的ACL功能简介

5月 22, 2017 |

权限控制主要应用场景及解决方案,
本文由博主http://www.javacoder.cn/?p=926整理,转载请注明出处,谢谢
1)WEB URL权限的控制
通过http filter链完成,比如

<http realm="Contacts Realm" use-expressions="false">
<intercept-url pattern="/login/impersonate" access="ROLE_SUPERVISOR"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
</http>

拥有ROLE_SUPERVISOR角色的用户才能访问/login/impersonate路径,ROLE_USER角色的用户可以访问其他的路径
2)数据权限和service层方法调用的权限控制

MethodSecurityInterceptor 配合使用PreAuthorize、PostAuthorize等注解实现

public interface BankService {
@PreAuthorize("hasRole('ROLE_SUPERVISOR') or "
+ "hasRole('teller') and (#account.balance + #amount >= -#account.overdraft)")
public Account post(Account account, double amount);
}

3)对read,write,create,delete,administration的控制
这就是本文将要介绍的spring的ACL功能
spring security自带的contacts-xml示例对该功能进行了演示,如果要使用该功能,该示例是学习该功能不二之选。本文也是基于该示例进行讲解的
该示例默认的AclService是基于HSQLDB数据库实现的,HSQLDB内存数据库我一时半会没有找到合适的控制台,所以改成了MySQL数据库,主要的改动是建表的SQL和JdbcMutableAclService bean定义时classIdentityQuery和sidIdentityQuery属性的指定,对应HSQLDB,当我们执行自动创建主键的insert语句后,可以通过"call identity()"获得刚产生的id,而MySQL的语法为"select LAST_INSERT_ID()",所以定义如下

<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
<constructor-arg ref="dataSource"/>
<constructor-arg ref="lookupStrategy"/>
<constructor-arg ref="aclCache"/>
<property name="classIdentityQuery" value="select LAST_INSERT_ID()"/>
<property name="sidIdentityQuery" value="select LAST_INSERT_ID()"/>
</bean>

spring security ACL的表的ER图如下,

spring_security_acl_model

各个表的简介如下:
users: 不属于ACL的表,用户表,userService会使用本表,users.USERNAME = acl_sid.SID,acl_sid有对应的记录表示同一个principal,所以大家可以看到ER图中没有外键关系
authorities:用于记录用户被授予的权限,authorities.AUTHORITY = acl_sid.SID,acl_sid即可以表示一个principal,也可以表示一个authority,通过acl_sid.PRINCIPAL字段来区分
contacts:是本例的实体表,对该表的记录进行CRWDA权限的控制,contacts.ID = acl_object_identity.OBJECT_ID_IDENTITY;
acl_class: 表示对哪个java entity进行权限控制,本例contacts表只有一条记录为'entity 'sample.contact.Contact';
acl_sid :security identity,根据PRINCIPAL字段的不同分别表示principal或者authority;
acl_object_identity:acl_object_identity.OBJECT_ID_IDENTITY = contacts.ID,acl_object_identity.OBJECT_ID_CLASS=acl_class.ID
and acl_object_identity.OWNER_SID= acl_sid.ID;分别对对应字段的引用,也就是说id及该entity的类型唯一地确定一条acl_object_identity记录,acl_object_identity是对实体记录的抽象。
acl_entry: acl_entry.SID = acl_sid.ID, acl_entry.ACL_OBJECT_IDENTITY = acl_object_identity.ID ;表示实际的授权。授权通过位相与存放在acl_entry.MASK字段中,read(0X1), write(0X2), create(0X4), delete(0X8), administration(0xF)

最重要类有AclService,及对应的实现JdbcMutableAclService。Acl及对应的实现AclImpl,Acl表示一个实体的权限分配,本例中为一个Contact记录的权限分配

Posted in: Spring Security

Comments are closed.