`
lengyun3566
  • 浏览: 452517 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
D59180b9-02f1-3380-840c-ea34da46143c
《Spring Secur...
浏览量:383408
社区版块
存档分类
最新评论

《Spring Security3》第七章第二部分翻译(高级ACL)(上)

 
阅读更多

 

高级ACL话题

         一些高级的话题在我们配置ACL环境时略过了,包括处理ACE许可授权,在运行时根据GrantedAuthority确定某种类型的ACL变化是否允许。既然现在我们已经有了一个运行环境,那我们要开始了解这些更高级的话题。

Permission如何工作

         许可授权(permission)只不过是简单的逻辑标识符用一个整数的二进制位来表示。一个访问控制条目对于SID的授权是基于逻辑与操作所有应用于这个条目的许可授权得到的位掩码。

         默认的Permission实现,即o.s.s.acls.domain.BasePermission定义了一系列的整数值来代表常用的ACL授权。这些整数值对应于单个位设置为整数,所以BasePermission. WRITE的值,对于的整数为1,按位的值就是212。它们如下图所示:



 你可以看到示例的许可授权掩码有二进制整数值为3,这是因为应用ReadWrite许可后就会具有这个许可授权值了。在这个图中,所有标准的单个整数授权值都是在BasePermission中作为静态常量定义的。你可能会回忆起来我们在构建ACL配置练习中在o.s.s.acls.AclEntryVoter里,使用过它们中的一个常量BasePermission.READ

BasePermission所包含的逻辑常量只是在访问控制条目中经常用到的,并且在Spring Security中没有特殊的语义。对于非常复杂的ACL实现,创建自己的许可授权是很常见的,以增强独立于域或业务的最佳实践。】

         一个经常困扰用户的问题是位掩码实际上是如何应用的,因为很多数据库要么不支持按位逻辑操作要么不支持可伸缩的方式。Spring ACL通过把按位进行许可授权计算放到应用中来解决这个问题,而不是放在数据库中。

         了解这个处理过程很重要,在这里我们能够看到AclEntryVoter怎样处理声明在方法上的许可授权(在我们的例子中,通过@Secured注解)到真正的ACL授权。下图阐述了针对安全实体的请求,Spring ACL评估声明的许可权限与相关ACE的过程:



 我们可以看到AclEntryVoter依赖实现o.s.s.acls.model.ObjectIdentityRetrievalStrategyo.s.s.acls.model.SidRetrievalStrategy接口的实现类,以获取适当的ObjectIdentitySids进行认证检查。关于这些策略有一个很重要的事情就是基于授权认证的上下文,默认的实现类如何决定要返回的ObjectIdentitySids

         ObjectIdentity有两个属性分别为typeidentifier,它们是根据运行时要检查的对象得到的,并用来声明ACE条目。默认的ObjectIdentityRetrievalStrategy使用全类名来填充type属性。identifier属性通过调用实际对象实例的Serializable getId()方法得到的结果进行填充(译者注:因此进行ACL授权的对象需要有getId这个方法)。

         【为了支持ACL检查你的对象并不需要实现接口,但是需要实现特定签名的一个方法这一点恐怕会让实现Spring Security ACL的开发人员感到惊讶。请事先规划,并确保你的域对象包含此方法!你也可以实现自己的ObjectRetrievalStrategy(或内置实现的子类)来调用你选择的一个方法。但遗憾的是,这个方法的名字和类型是不可配置的。】

         不幸的是,AclImpl的实际实现直接将配置的PermissionAclEntryVoter进行对比,但是Permission存储在ACE上在数据库中,不能使用按位逻辑操作。Spring Security社区关于这是否有意为之还有争论,但是不管怎样,当你声明一个拥有组合许可授权的用户时需要特别小心,要么AclEntryVoter必须配置上所有组合许可授权要么ACE需要忽略permission域本来可以配置多个值,而是要在每个ACE上只配置一个许可授权。

         如果你想在我们简单的场景下校验它,将我们授给ROLE_ADMIN SID的权限由Read许可修改为ReadWrite组合二进制掩码,也就是将其转换成3。这需要修改test-acl-data.sql

 

insert into acl_entry (acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)
select oi.id, 1, si.id, 3, true, true, true
from acl_object_identity oi, acl_sid si
where si.sid = 'ROLE_ADMIN';

 如果现在你作为管理员访问ACL保护的分类,你会被拒绝,即使我们已经在单个ACE上声明了你可以进行ReadWrite。(译者注:不得不说,在一点上Spring Security ACL有点弱。)

自定义ACL permission声明

         正如在讨论许可授权声明时所讲的那样,许可授权(permission)只不过是带有逻辑名的整数值。既然如此,可以扩展BasePermission来声明自己的许可权限。这里我们会涉及一个很简单的场景,创建一个新的ACL许可权限名为ADMIN_READ。这个权限只会授予给管理员用户,并分配给只有管理员才能读的资源。尽管这对于JBCP Pets站点是一个比较牵强的例子,但是这种类型的自定义权限在处理个人信息时很常用(如社会保险号等——可以回忆下我们在第一章:一个不安全应用的剖析中提到的PII)。

         让我们开始要支持这个所要进行的变化。第一步就是用我们的com.packtpub.springsecurity.security.CustomPermission来扩展BasePermission

 

package com.packtpub.springsecurity.security;
// imports omitted
public class CustomPermission extends BasePermission {
  protected CustomPermission(int mask, char code) {
    super(mask, code);
  }
  protected CustomPermission(int mask) {
    super(mask);
  }
  public static final Permission ADMIN_READ = new CustomPermission(1 << 5, 'M'); // 32
}

 接下来,我们要扩展o.s.s.acls.domain.PermissionFactory的默认实现o.s.s.acls.domain.DefaultPermissionFactory,来注册我们的自定义许可权限逻辑值。PermissionFactory的角色是将许可的二进制掩码转换成逻辑许可值(它可以在应用的其它部分被常量值或通过名字引用,如ADMIN_READ)。PermissionFactory需要所有的自定义许可权限在这里进行注册以便于查找。

我们实现com.packtpub.springsecurity.security.CustomPermissionFactory class类,如下:

 

package com.packtpub.springsecurity.security;
// imports omitted
public class CustomPermissionFactory extends DefaultPermissionFactory 
{
  public CustomPermissionFactory() {
    super();
    registerPublicPermissions(CustomPermission.class);
  }
  public CustomPermissionFactory(Class<? extends Permission> permissionClass) {
    super(permissionClass);
  }
  public CustomPermissionFactory(
      Map<String, ? extends Permission> namedPermissions) {
     super(namedPermissions);
  }
} 

我们可以看到增强了默认的构造方法以调用注册CustomPermission,使其作为一个可用的许可授权。

         【在本章的练习中我们不会强调基类的所有可用代码,但是建议你查看父类的其它功能并了解其在ACL系统中其它方面是如何使用的。例如,我们能够看到buildFromName方法在使用ACL自动以JSP tag中用到,这部分我们稍后展示。】

         我们需要配置CustomPermissionFactory并将其织入到BasicLookupStrategy。在dogstore-base.xml文件中要做以下的修改:

<bean class="org.springframework.security.acls.jdbc.BasicLookupStrategy" id="lookupStrategy">
  <constructor-arg ref="dataSource"/>
  <constructor-arg ref="aclCache"/>
  <constructor-arg ref="aclAuthzStrategy"/>
  <constructor-arg ref="aclAuditLogger"/>
  <property name="permissionFactory" ref="customPermissionFactory"/>
</bean>
<bean class="com.packtpub.springsecurity.security.CustomPermissionFactory"
 id="customPermissionFactory"/> 

现在,我们的自定义ACL权限在ACL框架中可用了。接下来,我们要添加一个新的管理员,他被明确分配这个权限到第二个分类“Dog Food”上。我们要添加以下内容到test-acl-data.sql上,以完成这个新授权的需要:

-- User SID
insert into acl_sid (principal, sid) values (true, 'admin2');
-- Category #2
insert into acl_object_identity (object_id_class,object_id_
identity,parent_object,owner_sid,entries_inheriting)
select cl.id, 2, null, sid.id, false
from acl_class cl, acl_sid sid
where cl.class='com.packtpub.springsecurity.data.Category' and sid.sid='admin2';
-- Give user 'admin2' access to category 2
-- "32" == 1 << 5
insert into acl_entry (acl_object_identity, ace_order, sid, mask, 
granting, audit_success, audit_failure)
select oi.id, 2, si.id, 32, true, true, true
from acl_object_identity oi, acl_sid si
where si.sid = 'admin2' and oi.object_id_identity = 2;
commit; 

你可以看到新的整数二进制掩码值32已经被ACE数据引用了——这会对应我们在代码中定义的新ADMIN_READ权限。在ACL_OBJECT_IDENTITY表中,“Dog Food”分类被它的主键(在object_id_identity列中)值2所引用。

         我们还需要在dogstore-base.xml文件中声明一个新的AclEntryVoter

<bean class="org.springframework.security.acls.AclEntryVoter" id="adminResourceReadVoter">
  <constructor-arg ref="aclService"/>
  <constructor-arg value="VOTE_ADMIN_READ"/>
  <constructor-arg>
    <array>
      <util:constant static-field="com.packtpub.springsecurity.security.CustomPermission.ADMIN_READ"/>
    </array>
  </constructor-arg>
  <property name="processDomainObjectClass"
 value="com.packtpub.springsecurity.data.Category"/>
</bean> 

除此以外,我们需要将这个投票器添加到访问决策管理器上,这个管理器负责在ACL保护方法的场景中,进行授权决策:

 

<bean class="org.springframework.security.access.vote.AffirmativeBased"
 id="aclDecisionManager">
  <property name="decisionVoters">
    <list>
      <ref bean="categoryReadVoter"/>
      <ref bean="adminResourceReadVoter"/>
    </list>
  </property>
</bean> 

最后,我们需要在方法声明本身上添加需要的角色,在IProductService接口声明上:

public interface IProductService {
  // other methods omitted
  @Secured({"VOTE_CATEGORY_READ","VOTE_ADMIN_READ"})
  public Collection<Item> getItemsByCategory(Category cat);
} 

  在所有配置完成后,我们可以启动站点并测试ACL权限。基于已配置的示例数据,以下不同用户点击分类时,应该发生的结果:

用户名

Pet apparel (分类1)

Dog Food (分类 2)

其它分类

admin

允许(通过ROLE_ADMIN SID ACE拥有READ权限)

拒绝

允许

admin2

允许(通过ROLE_ADMIN SID ACE拥有READ权限)

允许(通过安全实体SID ACE拥有ADMIN_READ权限)

允许

guest

拒绝

拒绝

允许

 

         可以看到即使使用我们简单的例子,也能扩展Spring ACL的功能。当然我们使用了很有限的方式来说明这个定义良好的访问控制系统的强大功能,这个系统是建立在安全实体、GrantedAuthority、单个域对象以及业务方法之上。

 

JSP中使用Spring Security JSP tag库启动ACL

         在第三章:增强用户体验和第五章中看到,Spring SecurityJSP tag库提供了暴露认证相关的数据给用户的功能以及基于各种规则限制能看到的内容。

         相同的tag库也能够内置地与使用ACL的系统交互。从我们上面简单的例子中,我们已经围绕首页上前两个分类配置了一个简单的ACL授权场景。

         让我们更进一步,使用<accesscontrollist>tag来隐藏用户实际不能访问的分类。

         请参考我们前面的表格来了解到此为止,我们已经配置的访问规则。

         我们将显示每个分类用<accesscontrollist>tag包围起来,声明对这个显示对象要进行的权限检查:

 

<c:forEach var="category" items="${categories}">
<security:accesscontrollist hasPermission="READ,ADMIN_READ" domainObject="${category}">
  <li><a href="category.do?id=${category.name}">${category.name} 
</a></li>
</security:accesscontrollist>
</c:forEach>

          请想一下,我们期望在这里发生什么——我们想要用户只能看到他有READADMIN_READ(我们自定义的许可权限)权限的条目。所以我们声明了一个逗号分隔的权限列表以及要进行检查的域对象(通过JSP EL的表达式${category}来指定)。

         在背后,这个tag的实现使用我们前面讨论的相同SidRetrievalStrategyObjectIdentityRetrievalStrategy,所以它与方法安全中使用的ACL具有相同的访问检查计算流程。

 

  • 大小: 14.2 KB
  • 大小: 60.2 KB
7
1
分享到:
评论
1 楼 hgmhgm86 2013-09-02  
翻译的真心不错!!!

相关推荐

    Spring Security 资料合集

    这三份资料——"实战Spring Security 3.x.pdf"、"Spring Security 3.pdf" 和 "Spring Security使用手册.pdf" 将深入探讨这些概念,并提供实践指导,帮助读者掌握如何在实际项目中应用Spring Security。通过学习这些...

    springSecurity3中文文档

    第二章:springsecurity起步 第三章:增强用户体验 第四章:凭证安全存储 第五章:精确的访问控制 第六章:高级配置和扩展 第七章:访问控制列表(ACL) 第八章:对OpenID开放 第九章:LDAP目录服务 第十章:使用...

    SpringSecurity笔记,编程不良人笔记

    - OAuth2:SpringSecurity支持OAuth2协议,实现第三方登录和API保护。 - JWT(JSON Web Tokens):可使用JWT进行状态less的认证,提高系统的可扩展性。 - CORS(Cross-Origin Resource Sharing):SpringSecurity...

    spring security 入门经典教程

    - 第2章:介绍了Spring Security的概况,可能包括了Spring Security的基本功能、特性以及它如何帮助开发者保护应用程序。 - 第3章:Spring Security架构与设计,这一章节着重讲述Spring Security的内部架构和设计...

    springsecurity所有jar包

    2. **spring-security-core**:这是Spring Security的基础模块,提供了安全核心服务,如安全性上下文、访问决策管理器、权限评估器等。它实现了基于角色的访问控制(RBAC)模型,处理用户、权限、角色等核心概念。 ...

    Pro+Spring+Security

    第二章:介绍Spring Security(Introducing Spring Security) - Spring Security概述:解释Spring Security框架的作用以及如何在Spring应用中集成安全功能。 - 基础配置:介绍如何设置Spring Security的基本配置,...

    Spring Security权限管理开发手册

    - **第2章:使用数据库管理用户权限** - **修改配置文件:** 更新Spring Security的配置文件,使其能够从数据库中读取用户信息和权限数据。 - **数据库表结构:** 设计并创建数据库表来存储用户信息和权限数据。 ...

    spring security 参考手册中文版

    第七部分 Spring数据集成 273 38. Spring Data&Spring安全配置 273 39. @Query中的安全表达式 273 第八部分 附录 274 40.安全数据库模式 274 40.1用户模式 274 40.1.1集团当局 274 40.2持久登录(记得我)架构 275 ...

    spring security4架包

    综上所述,这个"spring security4架包"涵盖了Spring Security的各个方面,从Web安全、用户认证、权限控制到测试支持和第三方服务集成,为构建安全的Java Web应用提供了全面的工具集。使用这些组件,开发者可以构建出...

    spring-security-2.0.5.jar2

    Spring Security是Spring生态系统的组成部分,主要负责应用程序的安全性,包括用户认证、权限控制和会话管理等。2.0.5版本虽已较为古老,但它的设计理念和核心机制对于理解现代版本仍有重要价值。 二、认证机制 1. ...

    spring-security-2.0.4.zip

    随着项目的成熟和社区的发展,Acegi被SpringSource(现在是Pivotal Software的一部分)正式接纳并重命名为Spring Security,以更好地融入Spring生态系统,并保持与Spring的紧密集成。 Spring Security的核心功能...

    spring security安全框架学习

    - Spring Security 3支持与其他身份验证服务集成,如OAuth用于API保护,OpenID用于第三方登录。 在"spring_security.sql"文件中,可能包含了创建上述数据库表的SQL脚本,用于演示Spring Security如何与数据库配合...

    spring-security3.1.4 完整的jar包

    3. **spring-security-config-3.1.4.RELEASE.jar**:配置模块允许开发者使用XML或注解来定义安全规则,如访问控制、角色分配等。它包含了表达式语言,使得在定义访问控制时可以使用自定义逻辑。 4. **spring-...

    spring 3 security

    Spring Security 3提供内置的CSRF防护机制,防止恶意第三方在用户浏览器中伪造请求。 7. **Web Expression Configuration** 在Spring Security 3中,可以通过XML或Java配置来定义安全规则,使用表达式来定义访问...

    SpringSecurit安全权限管手册

    2. **第二章:自定义数据库表结构** 在实际应用中,SpringSecurity的默认用户存储可能不符合需求。这一章会讲解如何自定义用户信息存储,比如使用自定义的UserDetailsService和JDBC用户存储,以便将用户信息存储在...

    2013-ProSpringSecurity

    ### 第2章:介绍Spring Security 这一章深入介绍了Spring Security框架的基础知识,包括其历史背景、设计理念以及与Spring框架之间的集成方式。通过本章的学习,读者能够理解Spring Security如何解决常见的安全性...

    Spring-Security:Spring安全课程

    8. **OAuth2集成**:Spring Security支持OAuth2协议,可以实现第三方服务的授权登录,如Google、Facebook等。 9. **RESTful API保护**:对于JSON Web Tokens (JWT) 和其他无状态认证机制,Spring Security也提供了...

Global site tag (gtag.js) - Google Analytics