0.8.3版本的net.sf.acegisecurity.providers.ProviderManager存在的一个问题

         首先说明,我用的是0.8.3版本。因为已经弄得差不多了,另外,看的一些材料都是针对0.8.3版本的,好像后面的版本跟0.8.3还是有不少的不同,所以也就不想换成新版本了。
        因为系统中可能存在两种类型的账号,一种是常见的用户名+密码,另一种是用认证锁(像IKey之类的),所以配了两个provider:
<bean id="authenticationManager"
  class="net.sf.acegisecurity.providers.ProviderManager">
  <property name="providers">
   <list>
    <ref bean="authenticationProvider" /><!--对于第一种账号-->
    <ref bean="authenticationProvider4Ikey" /><!--对于第二种账号-->
   </list>
  </property>
 </bean>

按书上说的,Acegi会遍历这些provider来进行验证。结果发现当我用第一种账号时,可以正常进行验证,可是用第二种时就无法通过验证(当然了,前提是这个账号是存在的)。检查配置,没发现什么错,很奇怪。把两个provider的顺序换了一下,现在第二种账号可以正常进行验证,可是第一种类型的却不行了。看来问题是出现在遍历这些provider上了。
       找了Acegi的原码来看,发现当使用provider进行验证时,如果第一个验证失败,则会用下一个provider进行验证,直至验证通过或是遍历完所有的provider。的确跟书上说的一样,可是怎么实际用起来就出错呢?实在看不出头绪,只好Debug,一步一步跟踪。终于发现问题所在。原来在provider验证失败后抛出异常,而在ProviderManager#doAuthentication()并没有对这个异常进行捕获,于是这个异常就接着很上抛了,结果是当第一个provider验证失败后,就会因为异常的出现而终止了doAuthentication()方法,所以后面的provider根本就没有机会发挥作用。
        找到问题所在了,接下来就是改了,最简单的作法当然就是在ProviderManager#doAuthentication()中加上对这个异常的捕获:
try{
         Authentication result = provider.authenticate(authentication);
         if (result != null) {
                    sessionController.afterAuthentication(authentication, result);
                    return result;
         }
}catch(Exception e){
   //TODO
}
       
   估计这个问题在后面的版本中应该是有改正了吧,找来1.0.1版本的原码,果然:
         try {
                    result = provider.authenticate(authentication);
                    sessionController.checkAuthenticationAllowed(result);
         } catch (AuthenticationException ae) {
                    lastException = ae;
                    result = null;
         }

也不知道0.8.3版本会不会还存在其他一些问题,看来还是得找个时间把Acegi换成最新的版本,本还想偷懒一下的。

posted on 2006-09-03 00:27 刺猬 阅读(387) 评论(0)  编辑  收藏 所属分类: Acegi

只有注册用户登录后才能发表评论。


网站导航: