- 浏览: 264888 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
panghaoyu:
不需要solr、mongodb、任何数据库、jsp\php\a ...
搜索关键字拼音智能提示实现 -
panghaoyu:
其实还有其他方法,比如可以嵌入搜索引擎的搜索自动提示js,就 ...
搜索关键字拼音智能提示实现 -
颖宝blingbling:
<div></div>
搜索关键字拼音智能提示实现 -
静夜独窗:
请问,这段代码哪里用到了Memcache,整个验证用cooki ...
JCaptcha+Memcache的验证码集群实现 -
liubang201010:
alfresco简体中文汉化包:
http://www.inn ...
Alfresco社区版本安装(linux)
ACL即访问控制列表(Access Controller List),它是用来做细粒度权限控制所用的一种权限模型。对ACL最简单的描述就是两个业务员,每个人只能查看操作自己签的合同,而不能看到对方的合同信息。
一、准备数据库和aclService
ACL所需的四张表,表结构见附录:附录 E, 数据库表结构。然后我们需要配置aclService,它负责与数据库进行交互。
CREATE TABLE `acl_sid` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`principal` tinyint(1) NOT NULL,
`sid` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_uk_1` (`sid`,`principal`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
CREATE TABLE `acl_class` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`class` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_uk_2` (`class`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
CREATE TABLE `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) NOT 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`),
CONSTRAINT `acl_object_identity_ibfk_1` FOREIGN KEY (`parent_object`) REFERENCES `acl_object_identity` (`id`),
CONSTRAINT `acl_object_identity_ibfk_2` FOREIGN KEY (`object_id_class`) REFERENCES `acl_class` (`id`),
CONSTRAINT `acl_object_identity_ibfk_3` FOREIGN KEY (`owner_sid`) REFERENCES `acl_sid` (`id`)
CREATE TABLE `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`),
CONSTRAINT `acl_entry_ibfk_1` FOREIGN KEY (`acl_object_identity`) REFERENCES `acl_object_identity` (`id`),
CONSTRAINT `acl_entry_ibfk_2` FOREIGN KEY (`sid`) REFERENCES `acl_sid` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
这四个表的说明如下:
?
1、ACL_SID让我们定义系统中唯一主体或授权(“SID”意思是“安全标识”——Spring Security Identity),是ACL认证对象。 它包含的列有ID,一个文本类型的SID,以及principal。
??? 其中,SID是Security ID的简称,表示一个被认证对象。记录一个用户名(USERBASE.NAME)或角色名(ROLES.NAME) 。如果按角色认证,SID就是对应的角色,如果按用户名认证,SID就是对应的用户名。用来表示是否使用文本显示引用的主体名或一个GrantedAuthority。
??? 而principal是认证规则。1 SID为用户名,0 SID为角色名。因此,对每个唯一的主体或GrantedAuthority都有单独一行。 在使用获得授权的环境下,一个SID通常叫做"recipient"授予者。
?
2、ACL_CLASS 让我们在系统中确定唯一的领域对象类。包含的列有ID和java类名。 因此,对每个我们希望保存ACL权限的类都有单独一行。其中,class是所要操作的域对象类型,它是域对象类型的全限定名。只有在此表中的CLASS,才被准许进行ACL授权及验证。
?
3、ACL_OBJECT_IDENTITY 为系统中每个唯一的领域对象实例保存信息。 列包括ID,指向ACL_CLASS的外键,唯一标识,所以我们知道为哪个ACL_CLASS实例提供信息,parent,一个外键指向ACL_SID 表,展示领域对象实例的拥有者,我们是否允许ACL条目从任何父亲ACL继承。 我们对每个领域对象实例有一个单独的行,来保存ACL权限。
1. 为acl配置cache
默认使用ehcache,spring security提供了一些默认的实现类。
<bean id="aclCache" class="org.springframework.security.acls.jdbc.EhCacheBasedAclCache">
<constructor-arg ref="aclEhCache"/>
</bean>
<bean id="aclEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheName" value="aclCache"/>
</bean>
在ehcache.xml中配置对应的aclCache缓存策略。
<cache
name="aclCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="3600"
overflowToDisk="true"
/>
2. 配置lookupStrategy
简单来说,lookupStrategy的作用就是从数据库中读取信息,把这些信息提供给aclService使用,所以我们要为它配置一个dataSource,配置中还可以看到一个aclCache,这就是上面我们配置的缓存,它会把资源最大限度的利用起来。
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
<constructor-arg ref="dataSource"/>
<constructor-arg ref="aclCache"/>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
<ref local="adminRole"/>
<ref local="adminRole"/>
<ref local="adminRole"/>
</list>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
</constructor-arg>
</bean>
<bean id="adminRole" class="org.springframework.security.GrantedAuthorityImpl">
<constructor-arg value="ROLE_ADMIN"/>
</bean>
中间一部分可能会让人感到困惑,为何一次定义了三个adminRole呢?这是因为一旦acl信息被保存到数据库中,无论是修改它的从属者,还是变更授权,抑或是修改其他的ace信息,都需要控制操作者的权限,这里配置的三个权限将对应于上述的三种修改操作,我们把它配置成,只有ROLE_ADMIN才能执行这三种修改操作。
3. 配置aclService
当我们已经拥有了dataSource, lookupStrategy和aclCache的时候,就可以用它们来组装aclService了,之后所有的acl操作都是基于aclService展开的。
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
<constructor-arg ref="dataSource"/>
<constructor-arg ref="lookupStrategy"/>
<constructor-arg ref="aclCache"/>
</bean>
二、使用aclService管理acl信息
当我们添加了一条信息,要在acl中记录这条信息的ID,所有者,以及对应的授权信息。下列代码在添加信息后执行,用于添加对应的acl信息。
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId());
MutableAcl acl = mutableAclService.createAcl(oid);
acl.insertAce(0, BasePermission.ADMINISTRATION,
new PrincipalSid(owner), true);
acl.insertAce(1, BasePermission.DELETE,
new GrantedAuthoritySid("ROLE_ADMIN"), true);
acl.insertAce(2, BasePermission.READ,
new GrantedAuthoritySid("ROLE_USER"), true);
mutableAclService.updateAcl(acl);
第一步,根据class和id生成object的唯一标示。
第二步,根据object的唯一标示,创建一个acl。
第三步,为acl增加ace,这里我们让对象的所有者拥有对这个对象的“管理”权限,让“ROLE_ADMIN”拥有对这个对象的“删除”权限,让“ROLE_USER”拥有对这个对象的“读取”权限。
最后,更新acl信息。
当我们删除对象时,也要删除对应的acl信息。下列代码在删除信息后执行,用于删除对应的acl信息。
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id);
mutableAclService.deleteAcl(oid, false);
使用class和id可以唯一标示一个对象,然后使用deleteAcl()方法将对象对应的acl信息删除。
三、使用acl控制delete操作
述代码中,除了对象的拥有者之外,我们还允许“ROLE_ADMIN”也可以删除对象,但是我们不会允许除此之外的其他用户拥有删除对象的权限,为了限制对象的删除操作,我们需要修改Spring Security的默认配置。
首先要增加一个对delete操作起作用的表决器。
<bean id="aclMessageDeleteVoter" class="org.springframework.security.vote.AclEntryVoter">
<constructor-arg ref="aclService"/>
<constructor-arg value="ACL_MESSAGE_DELETE"/>
<constructor-arg>
<list>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.DELETE"/>
</list>
</constructor-arg>
<property name="processDomainObjectClass" value="com.family168.springsecuritybook.ch12.Message"/>
</bean>
它只对Message这个类起作用,而且可以限制只有管理和删除权限的用户可以执行删除操作。
然后要将这个表决器添加到AccessDecisionManager中。
<bean id="aclAccessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter"/>
<ref local="aclMessageDeleteVoter"/>
</list>
</property>
</bean>
现在AccessDecisionManager中有两个表决器了,除了默认的RoleVoter之外,又多了一个我们刚刚添加的aclMessageDeleteVoter。
现在可以把新的AccessDecisionManager赋予全局方法权限管理器了。
<global-method-security secured-annotations="enabled"
access-decision-manager-ref="aclAccessDecisionManager"/>
然后我们就可以在MessageService.java中使用Secured注解,控制删除操作了。
@Transactional
@Secured("ACL_MESSAGE_DELETE")
public void remove(Long id) {
Message message = this.get(id);
list.remove(message);
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id);
mutableAclService.deleteAcl(oid, false);
}
实际上,我们最好不要让没有权限的操作者看到remove这个链接,可以使用taglib隐藏当前用户无权看到的信息。
<sec:accesscontrollist domainObject="${item}" hasPermission="8,16">
|
<a href="message.do?action=remove&id=${item.id}">Remove</a>
</sec:accesscontrollist>
8, 16是acl默认使用的掩码,8表示DELETE,16表示ADMINISTRATOR,当用户不具有这些权限的时候,他在页面上就看不到remove链接,也就无法执行操作了。
这比让用户可以执行remove操作,然后跑出异常,警告访问被拒绝要友好得多。
四、控制用户可以看到哪些信息
当用户无权查看一些信息时,我们需要配置afterInvocation,使用后置判断的方式,将用户无权查看的信息,从MessageService返回的结果集中过滤掉。
后置判断有两种形式,一种用来控制单个对象,另一种可以过滤集合。
<bean id="afterAclRead" class="org.springframework.security.afterinvocation.AclEntryAfterInvocationProvider">
<sec:custom-after-invocation-provider/>
<constructor-arg ref="aclService"/>
<constructor-arg>
<list>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.READ"/>
</list>
</constructor-arg>
</bean>
<bean id="afterAclCollectionRead" class="org.springframework.security.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
<sec:custom-after-invocation-provider/>
<constructor-arg ref="aclService"/>
<constructor-arg>
<list>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.READ"/>
</list>
</constructor-arg>
</bean>
afterAclRead可以控制单个对象是否可以显示,afterAclCollectionRead则用来过滤集合中哪些对象可以显示。[6]
对这两个bean都是用了custom-after-invocation-provider标签,将它们加入的后置判断的行列,下面我们为MessageService.java中的对应方法添加Secured注解,之后它们就可以发挥效果了。
@Secured({"ROLE_USER", "AFTER_ACL_READ"})
public Message get(Long id) {
for (Message message : list) {
if (message.getId().equals(id)) {
return message;
}
}
return null;
}
@Secured({"ROLE_USER", "AFTER_ACL_COLLECTION_READ"})
public List getAll() {
return list;
}
以上就是Spring Security支持的ACL,我们只演示了DELETE一种情况,就已经编写了如此之多的xml配置文件,很难想象随着对象的增多,这个配置工作要扩展到什么程度,如何才能像之前配置user和resource时,将这些acl的信息都配置到database中呢?目前还是一个我们正在考虑的问题。
一、准备数据库和aclService
ACL所需的四张表,表结构见附录:附录 E, 数据库表结构。然后我们需要配置aclService,它负责与数据库进行交互。
CREATE TABLE `acl_sid` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`principal` tinyint(1) NOT NULL,
`sid` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_uk_1` (`sid`,`principal`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
CREATE TABLE `acl_class` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`class` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_uk_2` (`class`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
CREATE TABLE `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) NOT 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`),
CONSTRAINT `acl_object_identity_ibfk_1` FOREIGN KEY (`parent_object`) REFERENCES `acl_object_identity` (`id`),
CONSTRAINT `acl_object_identity_ibfk_2` FOREIGN KEY (`object_id_class`) REFERENCES `acl_class` (`id`),
CONSTRAINT `acl_object_identity_ibfk_3` FOREIGN KEY (`owner_sid`) REFERENCES `acl_sid` (`id`)
CREATE TABLE `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`),
CONSTRAINT `acl_entry_ibfk_1` FOREIGN KEY (`acl_object_identity`) REFERENCES `acl_object_identity` (`id`),
CONSTRAINT `acl_entry_ibfk_2` FOREIGN KEY (`sid`) REFERENCES `acl_sid` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
这四个表的说明如下:
?
1、ACL_SID让我们定义系统中唯一主体或授权(“SID”意思是“安全标识”——Spring Security Identity),是ACL认证对象。 它包含的列有ID,一个文本类型的SID,以及principal。
??? 其中,SID是Security ID的简称,表示一个被认证对象。记录一个用户名(USERBASE.NAME)或角色名(ROLES.NAME) 。如果按角色认证,SID就是对应的角色,如果按用户名认证,SID就是对应的用户名。用来表示是否使用文本显示引用的主体名或一个GrantedAuthority。
??? 而principal是认证规则。1 SID为用户名,0 SID为角色名。因此,对每个唯一的主体或GrantedAuthority都有单独一行。 在使用获得授权的环境下,一个SID通常叫做"recipient"授予者。
?
2、ACL_CLASS 让我们在系统中确定唯一的领域对象类。包含的列有ID和java类名。 因此,对每个我们希望保存ACL权限的类都有单独一行。其中,class是所要操作的域对象类型,它是域对象类型的全限定名。只有在此表中的CLASS,才被准许进行ACL授权及验证。
?
3、ACL_OBJECT_IDENTITY 为系统中每个唯一的领域对象实例保存信息。 列包括ID,指向ACL_CLASS的外键,唯一标识,所以我们知道为哪个ACL_CLASS实例提供信息,parent,一个外键指向ACL_SID 表,展示领域对象实例的拥有者,我们是否允许ACL条目从任何父亲ACL继承。 我们对每个领域对象实例有一个单独的行,来保存ACL权限。
1. 为acl配置cache
默认使用ehcache,spring security提供了一些默认的实现类。
<bean id="aclCache" class="org.springframework.security.acls.jdbc.EhCacheBasedAclCache">
<constructor-arg ref="aclEhCache"/>
</bean>
<bean id="aclEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheName" value="aclCache"/>
</bean>
在ehcache.xml中配置对应的aclCache缓存策略。
<cache
name="aclCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="3600"
overflowToDisk="true"
/>
2. 配置lookupStrategy
简单来说,lookupStrategy的作用就是从数据库中读取信息,把这些信息提供给aclService使用,所以我们要为它配置一个dataSource,配置中还可以看到一个aclCache,这就是上面我们配置的缓存,它会把资源最大限度的利用起来。
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
<constructor-arg ref="dataSource"/>
<constructor-arg ref="aclCache"/>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
<ref local="adminRole"/>
<ref local="adminRole"/>
<ref local="adminRole"/>
</list>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
</constructor-arg>
</bean>
<bean id="adminRole" class="org.springframework.security.GrantedAuthorityImpl">
<constructor-arg value="ROLE_ADMIN"/>
</bean>
中间一部分可能会让人感到困惑,为何一次定义了三个adminRole呢?这是因为一旦acl信息被保存到数据库中,无论是修改它的从属者,还是变更授权,抑或是修改其他的ace信息,都需要控制操作者的权限,这里配置的三个权限将对应于上述的三种修改操作,我们把它配置成,只有ROLE_ADMIN才能执行这三种修改操作。
3. 配置aclService
当我们已经拥有了dataSource, lookupStrategy和aclCache的时候,就可以用它们来组装aclService了,之后所有的acl操作都是基于aclService展开的。
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
<constructor-arg ref="dataSource"/>
<constructor-arg ref="lookupStrategy"/>
<constructor-arg ref="aclCache"/>
</bean>
二、使用aclService管理acl信息
当我们添加了一条信息,要在acl中记录这条信息的ID,所有者,以及对应的授权信息。下列代码在添加信息后执行,用于添加对应的acl信息。
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId());
MutableAcl acl = mutableAclService.createAcl(oid);
acl.insertAce(0, BasePermission.ADMINISTRATION,
new PrincipalSid(owner), true);
acl.insertAce(1, BasePermission.DELETE,
new GrantedAuthoritySid("ROLE_ADMIN"), true);
acl.insertAce(2, BasePermission.READ,
new GrantedAuthoritySid("ROLE_USER"), true);
mutableAclService.updateAcl(acl);
第一步,根据class和id生成object的唯一标示。
第二步,根据object的唯一标示,创建一个acl。
第三步,为acl增加ace,这里我们让对象的所有者拥有对这个对象的“管理”权限,让“ROLE_ADMIN”拥有对这个对象的“删除”权限,让“ROLE_USER”拥有对这个对象的“读取”权限。
最后,更新acl信息。
当我们删除对象时,也要删除对应的acl信息。下列代码在删除信息后执行,用于删除对应的acl信息。
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id);
mutableAclService.deleteAcl(oid, false);
使用class和id可以唯一标示一个对象,然后使用deleteAcl()方法将对象对应的acl信息删除。
三、使用acl控制delete操作
述代码中,除了对象的拥有者之外,我们还允许“ROLE_ADMIN”也可以删除对象,但是我们不会允许除此之外的其他用户拥有删除对象的权限,为了限制对象的删除操作,我们需要修改Spring Security的默认配置。
首先要增加一个对delete操作起作用的表决器。
<bean id="aclMessageDeleteVoter" class="org.springframework.security.vote.AclEntryVoter">
<constructor-arg ref="aclService"/>
<constructor-arg value="ACL_MESSAGE_DELETE"/>
<constructor-arg>
<list>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.DELETE"/>
</list>
</constructor-arg>
<property name="processDomainObjectClass" value="com.family168.springsecuritybook.ch12.Message"/>
</bean>
它只对Message这个类起作用,而且可以限制只有管理和删除权限的用户可以执行删除操作。
然后要将这个表决器添加到AccessDecisionManager中。
<bean id="aclAccessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter"/>
<ref local="aclMessageDeleteVoter"/>
</list>
</property>
</bean>
现在AccessDecisionManager中有两个表决器了,除了默认的RoleVoter之外,又多了一个我们刚刚添加的aclMessageDeleteVoter。
现在可以把新的AccessDecisionManager赋予全局方法权限管理器了。
<global-method-security secured-annotations="enabled"
access-decision-manager-ref="aclAccessDecisionManager"/>
然后我们就可以在MessageService.java中使用Secured注解,控制删除操作了。
@Transactional
@Secured("ACL_MESSAGE_DELETE")
public void remove(Long id) {
Message message = this.get(id);
list.remove(message);
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id);
mutableAclService.deleteAcl(oid, false);
}
实际上,我们最好不要让没有权限的操作者看到remove这个链接,可以使用taglib隐藏当前用户无权看到的信息。
<sec:accesscontrollist domainObject="${item}" hasPermission="8,16">
|
<a href="message.do?action=remove&id=${item.id}">Remove</a>
</sec:accesscontrollist>
8, 16是acl默认使用的掩码,8表示DELETE,16表示ADMINISTRATOR,当用户不具有这些权限的时候,他在页面上就看不到remove链接,也就无法执行操作了。
这比让用户可以执行remove操作,然后跑出异常,警告访问被拒绝要友好得多。
四、控制用户可以看到哪些信息
当用户无权查看一些信息时,我们需要配置afterInvocation,使用后置判断的方式,将用户无权查看的信息,从MessageService返回的结果集中过滤掉。
后置判断有两种形式,一种用来控制单个对象,另一种可以过滤集合。
<bean id="afterAclRead" class="org.springframework.security.afterinvocation.AclEntryAfterInvocationProvider">
<sec:custom-after-invocation-provider/>
<constructor-arg ref="aclService"/>
<constructor-arg>
<list>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.READ"/>
</list>
</constructor-arg>
</bean>
<bean id="afterAclCollectionRead" class="org.springframework.security.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
<sec:custom-after-invocation-provider/>
<constructor-arg ref="aclService"/>
<constructor-arg>
<list>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
<util:constant static-field="org.springframework.security.acls.domain.BasePermission.READ"/>
</list>
</constructor-arg>
</bean>
afterAclRead可以控制单个对象是否可以显示,afterAclCollectionRead则用来过滤集合中哪些对象可以显示。[6]
对这两个bean都是用了custom-after-invocation-provider标签,将它们加入的后置判断的行列,下面我们为MessageService.java中的对应方法添加Secured注解,之后它们就可以发挥效果了。
@Secured({"ROLE_USER", "AFTER_ACL_READ"})
public Message get(Long id) {
for (Message message : list) {
if (message.getId().equals(id)) {
return message;
}
}
return null;
}
@Secured({"ROLE_USER", "AFTER_ACL_COLLECTION_READ"})
public List getAll() {
return list;
}
以上就是Spring Security支持的ACL,我们只演示了DELETE一种情况,就已经编写了如此之多的xml配置文件,很难想象随着对象的增多,这个配置工作要扩展到什么程度,如何才能像之前配置user和resource时,将这些acl的信息都配置到database中呢?目前还是一个我们正在考虑的问题。
发表评论
-
DelegatingFilterProxy原理
2013-01-18 15:02 2339DelegatingFilterProxy的原理及使用 ... -
Spring 3.x MVC 入门4 -- @ResponseBody & @RequestBody【转】
2013-01-08 11:39 1850@ResponseBody & @Request ... -
spring中配置quartz
2012-10-08 18:41 504<?xml version="1.0&q ... -
spring读取多个配置文件
2012-09-25 13:58 1031<bean id="systemP ... -
spring配置文件载入
2012-08-29 11:36 1378Spring配置文件的装载在Web.xml中配置: < ... -
Spring注解学习
2012-06-15 16:54 0一、@Autowire默认按照类型进行注入按类型装配依 ... -
spring3配置文件中的context:property-placeholder/元素[转]
2012-06-14 14:27 2791spring3配置文件中的context:property-p ... -
Spring mvc学习
2012-01-19 11:32 01.MVC :Model-View-Control 框架性质 ... -
web项目怎么启动spring容器
2012-01-04 17:28 59361. 首先,在web.xml中配置spring的配置文件的位置 ...
相关推荐
spring security acl 代码实例 spring security acl 代码实例spring security acl 代码实例spring security acl 代码实例spring security acl 代码实例spring security acl 代码实例
**Spring Security ACL 实现与扩展** **ACL 简介** 访问控制列表(Access Control List,简称 ACL)是一种用于...如需深入了解,请参考权限管理手册:http://www.family168.com/oa/springsecurity/html2009-08-19。
在Spring Security ACL中,你可以定义哪些用户或角色可以对特定的数据对象执行何种操作,例如读取、写入、删除等。这使得应用程序能够实现更灵活和强大的权限策略,而不仅仅是基于URL或方法的安全控制。 **1. ACL...
- **ACL (spring-security-acl.jar)**:提供了访问控制列表支持。 - **CAS (spring-security-cas-client.jar)**:提供了与 Central Authentication Service (CAS) 的集成支持。 - **OpenID (spring-security-...
在本例中,我们将探讨如何在Spring Security 3.0.4中使用ACL特性。 首先,ACL允许开发者定义对象级别的安全性,这意味着你可以控制用户对特定数据对象的操作权限。例如,你可以设定某个用户只能读取但不能修改特定...
spring-security-acl-2.0.4.jar
这三份资料——"实战Spring Security 3.x.pdf"、"Spring Security 3.pdf" 和 "Spring Security使用手册.pdf" 将深入探讨这些概念,并提供实践指导,帮助读者掌握如何在实际项目中应用Spring Security。通过学习这些...
- `ACL-spring-security-acl.jar`:提供了基于 ACL 的访问控制功能。 - `CAS-spring-security-cas-client.jar`:支持 CAS 协议的单点登录功能。 - `OpenID-spring-security-openid.jar`:支持 OpenID 身份验证。 ...
在Spring Security 4.0.0中,这些jar包一起工作,提供了一套完整的解决方案,用于实现用户认证(验证用户身份)和授权(决定用户是否允许访问特定资源)。例如,`spring-security-core`负责基本的认证和授权逻辑,`...
它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制...
在本笔记中,我们将深入探讨SpringSecurity的核心概念、配置以及如何与SpringBoot结合使用。 1. **SpringSecurity核心概念** - **Filter Chain**: SpringSecurity通过一系列过滤器实现其安全功能,这些过滤器构成...
在3.0版本中,Spring Security 已经相当成熟,提供了丰富的特性来保障应用的安全性。 在开始使用Spring Security时,了解并正确引入必要的jar包是至关重要的。以下是你提供的压缩包文件中的关键组件: 1. **spring...
- **发展历程**:Spring Security的发展历程可以追溯到早期的ACEGI Security项目,后来被集成到Spring框架中,并经过多次迭代更新,形成了如今功能强大且灵活的Spring Security框架。 - **获取方式**: - **项目...
这个特定的版本,Spring Security 2.0.5,虽然相对较老,但仍然值得探讨,因为它包含了早期的安全概念,这些概念在后续的版本中得到了发展和改进。 **一、核心组件** 1. **Filter Chain**: Spring Security 的核心...
spring-security-acl-2.0.4.jar spring-security-core-2.0.4.jar spring-security-core-tiger-2.0.4.jar spring-security-taglibs-2.0.4.jar spring-support-2.0.8.jar spring-web-2.0.8.jar spring-webmvc-2.0.8....
通常,只需要包括`spring-security-acl`、`spring-security-core`、`spring-security-core-tiger`和`spring-security-taglibs`等核心库。 接着,在`web.xml`中配置DelegatingFilterProxy,将所有HTTP请求路由到...
spring security 3.1.4的release包 需要的可以拿走
- **ACL (`spring-security-acl.jar`)**: 支持基于 ACL (Access Control List) 的细粒度访问控制。 - **CAS (`spring-security-cas.jar`)**: 集成 CAS (Central Authentication Service) 协议的支持。 - **OpenID...