RSS
热门关键字:  java  Ajax  JSP  JSF  Struts
当前位置 : 首页>Struts>列表

使用Acegi实现多种用户登录

来源: 作者: 时间:2007-09-19 点击:


  重新回到FilterChainProxy的配置,看到它调用了authenticationProcessingFilter这个Filter。让我们看看它的配置:

<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/login.jsp?error=true"/>
<property name="defaultTargetUrl" value="/"/>
<property name="filterProcessesUrl" value="/j_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>

  authenticationProcessingFilter的其中一个作用就是获取客户端提交的用户名和密码,将它们封装为一个Token,传递给authenticationManager的authenticate方法,由后者负责验证。

  看看authenticationManager的配置:

<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>

  authenticationManager依次调用每个provider的authenticate方法。如果某个provider验证成功则返回;如果所有的验证都不成功,则抛出异常。

  让我们看看daoAuthenticationProvider的配置:

<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDao"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
</bean>

  daoAuthenticationProvider在authenticate方法中调用retrieveUser方法取得用户信息,执行基本的验证,然后调用additionalAuthenticationChecks执行附加的验证(比如验证密码是否正确)。在retrieveUser方法中调用userDetailsService的loadUserByUsername方法取得用户信息,而userDetailsService是一个名为userDao的bean。让我们看看userDao的配置:

<bean id="userDao" class="cn.net.cogent.summer.extension.appfuse.dao.hibernate.EmployeeDaoHibernate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

  userDao实现了Acegi的UserDetailsService接口,该接口只有loadUserByUsername方法。loadUserByUsername方法根据传入的username取得相应的Employee对象(Employee实现了UserDetails接口),该对象返回给daoAuthenticationProvider,由它和authenticationManager联合完成验证的任务。

  以上对Acegi对表单验证过程进行了简单对分析,限于篇幅,无法深入分析源码。尽管Acegi调用了多个Filter来完成验证过程,关键点却在三处:

   1.在客户端输入身份验证信息,包括用户名和密码
   2.AuthenticationProcessingFilter取出用户名和密码,封装为一个Token往后传递
   3.DaoAuthenticationProvider从系统中找出用户资料,并和ProviderManager一起执行验证

  实现多种用户登录

  很明显,要让系统识别不同种类的用户,必须设立一个用户类型标志。问题就转化为:

   1.用户在客户端输入身份信息时系统就必须设立相应的标志
   2.该标志如何传递到DaoAuthenticationProvider
   3.DaoAuthenticationProvider如何识别该标志,并从相应类型的用户中找到指定用户

  我不打算改动Acegi的源码,只打算扩展出我需要的功能。

  首先在登录页面中加入用户类型标志j_userkind。在登录页面中加入如下代码:

<input type="hidden" name="j_userkind" id="j_userkind" value="0">

  其中0代码员工,1代码客户。可以考虑在登录页面中增加一个选项,如果用户要以员工身份登录,则把j_userkind置为0;如果用户要以客户身份登录,则把j_userkind置为1。也可以提供两个登录页面,其中一个员工专用(j_userkind被强制置为0),另一个客户专用(j_userkind被强制置为1)

  系统如何根据收到的用户类型标志去读取指定的用户呢?如果在代码中写死(比如当用户类型标志=0时,读取员工;当用户类型标志=1时,读取客户)非常不好,还是通过配置来确定比较灵活。首先编写UserKindComparisonAware接口:

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
Google Adsense
相关文章