《Spring Security3》第七章第二部分翻译(高级ACL)(下)
?
支持ACL的Spring表达式语言
?
<bean id="methodExprHandler"> <property name="permissionEvaluator" ref="aclPermissionEvaluator"/></bean><bean id="aclPermissionEvaluator"> <constructor-arg ref="aclService"/> <property name="permissionFactory" ref="customPermissionFactory"/></bean>
?我们更新的methodExprHandler的bean定义,配置了o.s.s.access.PermissionEvaluator的实现(默认的PermissionEvaluator实现会拒绝所有的许可认证检查)。o.s.s.acls.AclPermissionEvaluator使用了AclService及相关的类去实际检查SpEL表达式声明的许可权限。
@PostFilter("hasPermission(filterObject, 'READ') or hasPermission(filterObject, 'ADMIN_READ')")Collection<Category> getCategories();
?现在,重启应用并比较以匿名用户、admin、admin2进入时首页的分类列表。注意这个显示列表是如何通过ACL许可授权完成的?我们可以看到SpEL的hasPermission方法很好的与使用ACL的应用通过方法安全注解结合起来。
易变的ACL(Mutable ACLs)和授权
<bean width="73">
<bean id="txManager" ref="dataSource"/></bean>?
<bean init-method="aclBootstrap"/>?
package com.packtpub.springsecurity.security;// imports omittedpublic class AclBootstrapBean { @Autowired MutableAclService mutableAclService; @Autowired IProductDao productDao; @Autowired PlatformTransactionManager transactionManager;?
public void aclBootstrap() {// domain data to set upCollection<Category> categories = productDao.getCategories();Iterator<Category> iterator = categories.iterator();final Category category1 = iterator.next();final Category category2 = iterator.next();
?我们需要引用实际要保护的域对象以便于为它们创建ACL。回忆一下,我们的ACL启动SQL只对前两个分类添加条目,所以我们要把它们从ProductDAO中取出来。
// needed because MutableAclService requires a current authenticated principalGrantedAuthorityImpl roleUser = new GrantedAuthorityImpl("ROLE_USER");GrantedAuthorityImpl roleAdmin = new GrantedAuthorityImpl("ROLE_ADMIN");UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("admin","admin",Arrays.asList(new GrantedAuthority[]{roleUser, roleAdmin}));SecurityContextHolder.getContext().setAuthentication(token);
// sidsfinal Sid userRole = new GrantedAuthoritySid("ROLE_USER");final Sid adminRole = new GrantedAuthoritySid("ROLE_ADMIN");// usersfinal Sid adminUser = new PrincipalSid("admin");final Sid admin2User = new PrincipalSid("admin2");
// all interaction with JdbcMutableAclService must be within a transactionTransactionTemplate tt = new TransactionTemplate(transactionManager); tt.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { // category 1 ACL MutableAcl createAclCategory1 = mutableAclService.createAcl(new ObjectIdentityImpl(category1)); createAclCategory1.setOwner(adminRole); createAclCategory1.insertAce(0, BasePermission.READ, adminRole, true); mutableAclService.updateAcl(createAclCategory1); // category 2 ACL MutableAcl createAclCategory2 = mutableAclService.createAcl(new ObjectIdentityImpl(category2)); createAclCategory2.setOwner(admin2User); createAclCategory2.insertAce(0, CustomPermission.ADMIN_READ, admin2User, true); mutableAclService.updateAcl(createAclCategory2);}});SecurityContextHolder.clearContext();}}?
<bean id="ehCacheManagerBean"/><bean id="ehCacheFactoryBean"> <property name="cacheManager" ref="ehCacheManagerBean"/></bean>?
<bean name="code"><bean id="lookupStrategy"> <constructor-arg ref="dataSource"/> <constructor-arg ref="ehCacheAclCache"/> <constructor-arg ref="aclAuthzStrategy"/> <constructor-arg ref="aclAuditLogger"/></bean>
?当这些配置完成(并且Ehcache运行时JAR在你的classpath中),ACL数据将会基于Ehcache缓存管理器的配置进行缓存。
Spring ACL怎样使用Ehcache<bean id="ehCacheFactoryBean"> <property name="cacheManager" ref="ehCacheManagerBean"/> <property name="cacheName" value="springAclCacheRegion"/></bean>
?奇怪的是,除了Javadoc以外,Spring Core中对于Ehcache的支持没有任何正规的文档。如果使用Spring ACL和Ehcache对你很重要,那你很可能需要自己深入研读代码。
?
?
?
?