原文地址:http://www.xx566.com/detail/172.html
之前Spring Security 2.0 多登录入口的实现与配置中, 我们简单的介绍了通过Spring Security 2.0多登陆入口的实现,通过几天的学习,对Spring Security的机制有了些简单的了解,Spring Security 3.0版本相比Spring Security 2.0有了很大的调整,内部进行了重构与设计优化,本篇,我们就来学习一下基于Spring Security 3.0多登陆入口的实现与配置。
具体的需求:系统中有两种用户类型,代理和管理员,在登录的时候需要区分代理和管理员的登录页面,不同的登录表单提交成功后进入的是同样的主页,在退出系统的时候,需要根据用户的类型再次返回到不同的登录页面。那么问题来了:我们应该怎样进行spring security的配置,以实现多登陆入口呢?
spring security登录表单提交对应的action为/j_spring_security_check,我们需要根据不同的登录页面区分为:/j_spring_security_check,/admin/j_spring_security_check,为了区分,我们需要在Spring Security的配置文件中,增加两个过滤器,分别处理前台和后台的登录请求,如下:
<!-- 前台用户登陆 --> <bean id="frontLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="filterProcessesUrl" value="/j_spring_security_check"/> <property name="authenticationFailureHandler" ref="frontFailureHandler"/> <property name="authenticationSuccessHandler" ref="frontSuccessHandler"/> </bean> <!-- 后台用户登陆 --> <bean id="adminLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="filterProcessesUrl" value="/admin/j_spring_security_check"/> <property name="authenticationFailureHandler" ref="adminFailureHandler"/> <property name="authenticationSuccessHandler" ref="adminSuccessHandler"/> </bean>
对上面配置中的属性,做一些说明:
filterProcessesUrl |
登录处理URL |
authenticationFailureHandler |
验证失败处理 |
authenticationSuccessHandler |
验证成功处理 |
这里的ref="authenticationManager",我们需要在Spring Security的配置文件中声明,对于提交的表单请求,我们需要配置authentication-provider,和实现自己的ApplicationListener,如下:
<security:authentication-manager alias="authenticationManager"> <security:authentication-provider user-service-ref="customUserDetailsService"> <security:password-encoder hash="md5"/> </security:authentication-provider> </security:authentication-manager> <bean name="myApplicationListener" class="security.MyAuthenticationSuccessHandler"/>
对于验证失败或成功,我们也需要实现自己的处理Handler,如下:
<!--前台登录失败处理--> <bean id="frontFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login.jsp?error=true"/> </bean> <!-- 前台登录成功处理 --> <bean id="frontSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"> <property name="alwaysUseDefaultTargetUrl" value="true"/> <property name="defaultTargetUrl" value="/background/index.do"/> </bean> <!--后台登录失败处理--> <bean id="adminFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/admin/login.jsp?error=true"/> </bean> <!-- 后台登录成功处理 --> <bean id="adminSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"> <property name="alwaysUseDefaultTargetUrl" value="true"/> <property name="defaultTargetUrl" value="/background/index.do"/> </bean>
对于不同用户退出系统时,我们也需要进行特殊处理,正常的退出请求是:/j_spring_security_logout,我们需要根据用户的类型,使 用不同的退出action:/j_spring_security_logout,/admin/j_spring_security_logout,与 登录类似,我们也需要增加两个用于前后台用户注销的过滤器,如下:
<!-- 前台用户注销 --> <bean id="frontLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <constructor-arg value="/"/> <constructor-arg> <list> <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> </list> </constructor-arg> <property name="filterProcessesUrl" value="/j_spring_security_logout"/> </bean> <!-- 后台用户注销 --> <bean id="adminLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <constructor-arg value="/admin/"/> <constructor-arg> <list> <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> </list> </constructor-arg> <property name="filterProcessesUrl" value="/admin/j_spring_security_logout"/> </bean>
最后,我们需要配置security:http,加入指定的登录或注销的过滤器,如下:
<!-- access-denied-page配置访问失败页面 --> <security:http auto-config="false" entry-point-ref="loginUrlFilterEntryPoint" access-denied-page="/common/jsp/403.jsp"> <security:intercept-url pattern="/login.jsp" filters="none"/> <security:intercept-url pattern="/admin/login.jsp" filters="none"/> <!-- 登录过滤器 --> <security:custom-filter before="FORM_LOGIN_FILTER" ref="frontLoginFilter"/> <security:custom-filter position="FORM_LOGIN_FILTER" ref="adminLoginFilter"/> <!-- 注销过滤器 --> <security:custom-filter before="LOGOUT_FILTER" ref="frontLogoutFilter"/> <security:custom-filter position="LOGOUT_FILTER" ref="adminLogoutFilter"/> <!-- 会话管理配置,配置session timeout页面--> <security:session-management invalid-session-url="/common/jsp/300.jsp"> </security:session-management> </security:http> <bean name="loginUrlFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <property name="loginFormUrl" value="/"/> </bean>
这里感谢一下这些文章,都是Spring Security的多登陆入口的一些精彩文章,也可以作为学习SpringSecurity的参考文章,不过当然最好的学习资料还是官方的文档。
Spring Security 3.0 多页面登录配置
Spring Security 3的一些体会
Spring 3之MVC & Security简单整合开发(二)
最后附上完整的Spring Security.xml文件,给大家做个参考:http://git.oschina.net/realfighter/xx566-diary/blob/master/src/applicationContext-security3.xml