Acegi 的扩展

    年刚过,还很懒,这个东东年前都开始关注了,今天把学习成果总结一下。
    Acegi,一个安全系统,拦截器和面向接口的编程方式,支持ACL、JAAS基于Spring.我的理解其价值在于:replace Container-Managed Authentication,将安全这一块脱离具体j2ee容器,将来需要迁移时少一些麻烦,它足够强大,可以给web系统甚至cs应用提供足够的安全保护机制。这是一个常用的轮子,造得不错哟。

不过,acegi的学习曲线很陡峭,在web.xml配置了一堆的Filter之后,还需要配置spring的bean,仍然是一堆,好在先跑起了demo(0.6.1 quick-start)增加了一点信心。

先记下一个概念: 
Authentication 认证:验证一个用户的身份,你说你是大人物某某,你说是就是呀,请看证件,或介绍信等。最常用的是用户名+口令,还有电子证书等.
    在 bean 配置中,需要关注的几个关键bean,在后面的扩展中需要用到:
 1 AuthenticationManager 用于认证ContextHolder中的Authentication对象。给多种的认证方式留下了接口。

2 AccessDecissionManager 用于授权一个特定的操作,这里有一个授权策略问题,三个实现类分别为:
    AffirmativeBased 只需有一个投票赞成即可通过(最常用);allowIfAllAbstainDecisions属性值默认为false,意思是如果所有的授权投票是都是弃权,则通不过授权检查。
    ConsensusBased 需要大多数投票赞成即可通过;
    UnanimousBased 需要所有的投票赞成才能通过(悲观吧)。

3 ObjectDefinitionSource 描述角色与资源的匹配方式。

以上三个bean装配成为一个filterInvocationInterceptor,它将用来组装securityEnforcementFilter,之后的bean先不考虑了,因为扩展时用不到,照抄即可。


例子是比较简易的,要想让应用在实际项目中,首先需要解决以下两个问题:
1 基于数据库的用户认证,一般是用户名+密码,我的作法是:
  1.1 使你的User(Pojo或domain object)实现acegi中的这个接口:UserDetails,当然,如果你不想这么作,也可以加一个中间层,包装一下啦。
      这个接口只有一个方法 public GrantedAuthority[] getAuthorities();即返回该用户的角色列表.
  1.2 自己实现这个接口PasswordAuthenticationDao,不管你用hibernate还是ibatis.
      public UserDetails loadUserByUsernameAndPassword(String username, String password);
      很明显,需要从数据库中验证用户名和口令。
  1.3 开始装配:
        <bean id="myPwdAuthenticationDAO" class="net.chage.sm.dao.ibatis.AuthenticationDAOiBatis">
          <property name="dataSource"> <ref bean="dataSource" /> </property>
          <property name="sqlMapClient"><ref bean="sqlMap"/></property>
        </bean>    
   
     <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.PasswordDaoAuthenticationProvider">
        <property name="passwordAuthenticationDao"><ref bean="myPwdAuthenticationDAO"/></property>
        <property name="userCache"><ref local="userCache"/></property>
 </bean>
2 例子中url和角色的匹配关系也是固定的,如下:
   <property name="objectDefinitionSource">
   <value>
       CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
       PATTERN_TYPE_APACHE_ANT
      /admin/**=ROLE_ADMIN
      /contract.do*=ROLE_XXX
   </value>
  </property>


  如果这一块也需要从database中取,可以这么来实现:新建一个类extending PathBasedFilterInvocationDefinitionMap,
  使用其addSecureUrl来增加匹配信息。我写的是一个超简单的类,只为说明问题:
  package com.head.acegisecurity;

   import net.sf.acegisecurity.intercept.web.PathBasedFilterInvocationDefinitionMap;
   import net.sf.acegisecurity.ConfigAttributeDefinition;
   import net.sf.acegisecurity.ConfigAttribute;

   public class CjObjectDefinitionSource extends
  PathBasedFilterInvocationDefinitionMap {
 public CjObjectDefinitionSource(){
  super();
  ConfigAttributeDefinition definition = new ConfigAttributeDefinition();
  ConfigAttribute att = new MyConfigAttribute();
  definition.addConfigAttribute(att);
  this.addSecureUrl("/admin/**",definition);
 }
     class MyConfigAttribute implements ConfigAttribute{
 public String getAttribute(){
  return "ROLE_ADMIN";
 }
     }
   }
   然后配置:
   <bean id="myObjectDefinitionSource" class="com.head.acegisecurity.CjObjectDefinitionSource"/>
   <bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
       <property name="authenticationManager"><ref local="authenticationManager"/></property>
       <property name="accessDecisionManager"><ref local="accessDecisionManager"/></property>
    <property name="objectDefinitionSource"><ref local="myObjectDefinitionSource"/></property>
   </bean>
   最后,再说一下,acegi确实是一个优秀的安全框架,灵活强大,即使你用不上它,也可以从它的设计中汲取灵感。
  

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值