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

使用Acegi实现多种用户登录

来源: 作者: 时间:2007-09-19 点击:
  Acegi提供了多种身份验证方式(表单验证,CAS等),但只允许一种用户登录,而就个人了解,有一些系统是需要多种用户登录的。比如企业的员工需要登录并使用系统,企业也允许客户登录系统并使用有限的功能。以下尝试剖析Acegi的表单验证过程,并给出一种允许多种用户登录的方案。本方案基本达到“能用”的目的,但不一定是最佳方案。希望这篇文章能起到抛砖引玉的作用,给各位朋友一点参考,也希望各位提出有益的建议。

  Acegi的表单验证方式简要分析

  一个使用Acegi的表单验证的登录页面通常需要在表单提交时request的j_username和j_password参数赋值,即用户名和密码,而表单则提交到Acegi设定到验证地址。例如:

<form method="post" id="loginForm" action="<c:url value='/j_security_check'/>" >
<input type="text" name="j_username" id="j_username" />

<input type="password" name="j_password" id="j_password" />

<input type="submit" name="login" value="Login" />
</form>

  服务器的Servlet容器收到请求后会传递给Acegi的FilterToBeanProxy,这需要在web.xml中进行配置。例如:

<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

  FilterToBeanProxy基本上只起到调用转发的作用。在它的doFilter方法中会找到类型为FilterChainProxy的bean,调用后者的doFilter方法,同时把request、response会chain参数都传递过去。代码如下:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (!initialized) {
doInit();
}

delegate.doFilter(request, response, chain);
}

  上面的代码中的delegate就是找到的类型FilterChainProxy的bean。FilterChainProxy的典型配置如下:

<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
</value>
</property>
</bean>

  对于上面的配置,引用一段Acegi联机帮助中的说明来帮助理解:

Internally Acegi Security will use a PropertyEditor to convert the string presented in the above XML fragment into a FilterInvocationDefinitionSource object. What's important to note at this stage is that a series of filters will be run - in the order specified by the declaration - and each of those filters are actually the <bean id> of another bean inside the application context.

  实际上,FilterChainProxy的doFilter方法会执行如下处理:

    1.读取配置,如果配置为空,则直接调用chain.doFilter,返回
    2.如果配置不为空,则根据配置找到各个bean,放入Filter数组中。如果配置中没有配置任何bean,则直接调用chain.doFilter,返回
    3.FilterChainProxy创建一个VirtualFilterChain对象,并将chain封装为一个FilterInvocation对象,将它和Filter数组一起传递给VirtualFilterChain的构造函数。VirtualFilterChain的构造函数初始化了一个指针currentPosition,指向Filter数组的第一个元素additionalFilters[0]
    4.FilterChainProxy调用VirtualFilterChain的doFilter方法,在该方法中将指针currentPosition前移,调用additionalFilters[0]的doFilter方法。注意这里VirtualFilterChain把自身作为参数传递给additionalFilters[0]的doFilter方法,这样additionalFilters[0]的doFilter方法最后会调用VirtualFilterChain的doFilter方法,这样控制就又回到了VirtualFilterChain!于是VirtualFilterChain又将currentPosition前移,调用additionalFilters[1]的doFilter方法......
    5.当additionalFilters中所有元素的doFilter都执行完毕,VirtualFilterChain执行fi.getChain().doFilter,而fi.getChain()的值就是FilterChainProxy的doFilter方法中的参数chain的值。这样我们就理解了FilterChainProxy是怎样让调用兜了个圈,又传递出去的。

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