spring seurity 2中session的处理

由于种种关系,虽然spring security 3出了很久了,但还是项目中只能用
spring security 2,发现spring security 2真是十分多东西了,
其中比如象在struts2中和轻易写的session管理等,在spring security 2中都要
仔细研究文档,花点心思,这里首先推荐两篇网上为数不多的spring security2
的中文文档给大家学习,还有代码,先看这两篇:

http://www.blogjava.net/redhatlinux/archive/2008/08/20/223148.html
http://www.blogjava.net/redhatlinux/archive/2008/09/01/226010.html

  然后看完这两篇后,就可以开始吧。首先要解决的问题,是如何登录后,保存用户的session,其实这个可以
替换掉spring security 2中的authenticationProcessingFilter。
  先来看下application-security.xml的配置文件,注意本文说的依然是2的配置

首先是开始部分:
<ss:http auto-config="false" access-denied-page="/common/403.jsp"  entry-point-ref="authenticationProcessingFilterEntryPoint">

   注意,这里要把auto-config设置为false,并且同时要删除原先的:
 

Java代码  收藏代码
  1. <ss:form-login login-page="/login.action"  
  2.         authentication-failure-url="/login.action?error=true"  
  3.         default-target-url="/" always-use-default-target="true" />  


    再来看下这个插入点:

Java代码  收藏代码
  1. <bean id="authenticationProcessingFilterEntryPoint"  
  2.     class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">  
  3.     <property name="loginFormUrl" value="/login.action" />  
  4.   
  5.     <property name="forceHttps" value="false" />  
  6. </bean>  


   接下来,建立自定义的类MyAuthenticationProcessingFilter,代码如下:

  

Java代码  收藏代码
  1. ublic class MyAuthenticationProcessingFilter extends  
  2.         AuthenticationProcessingFilter {  
  3.   
  4. protected void onSuccessfulAuthentication(HttpServletRequest request,  
  5.             HttpServletResponse response, Authentication authResult)  
  6.             throws IOException {  
  7.         super.onSuccessfulAuthentication(request, response, authResult);  
  8.   
  9.           
  10.           
  11.         Object obj = SecurityContextHolder.getContext().getAuthentication()  
  12.                 .getPrincipal();  
  13.         if (obj instanceof UserDetails) {  
  14.   
  15.             userId = ((UserInfo) obj).getUserid();  
  16.             username= ((UserInfo) obj).getUsername();  
  17.               
  18.         }  
  19.   
  20.         request.getSession().setAttribute("userId", userId);  
  21.   
  22.   
  23.   
  24. }  

 

   可以看到,继承了AuthenticationProcessingFilter就可以了,在
onSuccessfulAuthentication方法中,可以进行session的保存了!
接下来要在配置文件中进行配置,注册替换掉原来的,如下:
  
 

Java代码  收藏代码
  1. <ss:logout logout-success-url="/login.action" />  
  2.   
  3. <ss:authentication-manager alias="authenticationManager" />  
  4.     <bean id="authenticationProcessingFilter"  
  5.         class="com.liao.security.MyAuthenticationProcessingFilter">  
  6.         <ss:custom-filter before="AUTHENTICATION_PROCESSING_FILTER" />  
  7.         <property name="defaultTargetUrl" value="/" />  
  8.         <property name="filterProcessesUrl" value="/j_spring_security_check" />  
  9.         <property name="authenticationFailureUrl" value="/login.action?error=true" />  
  10.         <property name="authenticationManager" ref="authenticationManager" />  
  11.     </bean>  



   可以看到,其实就是我们自定义的过滤器,摆放在spring security 2中的
AUTHENTICATION_PROCESSING_FILTER前面了;


   这样,我们就完成了第一个功能,可以在spring security 2中试用session了!


2) 显示没有权限的页面
    当没有权限的页面时,一般的显示方法是
<ss:http auto-config="false" access-denied-page="/common/403.jsp">
   但又有资料说到,如果要动态,不用一个固定的403.jsp的话,可以自定义
access-denied-handler,于是实验了下,用的是spring 2.5+spring security 2.0.4,
  

Java代码  收藏代码
  1. <bean id="exceptionTranslationFilter"  
  2.         class="org.springframework.security.ui.ExceptionTranslationFilter">  
  3.         <property name="accessDeniedHandler" ref="accessDeniedHandler" />  
  4.   
  5.         <property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint" />  
  6.     </bean>  
  7.     <!-- 处理AccessDeniedException -->  
  8.     <bean id="accessDeniedHandler" class="org.springframework.security.ui.AccessDeniedHandlerImpl">  
  9.   
  10.   
  11.         <property name="errorPage" value="/common/403.jsp" />  
  12.     </bean>  
  13.   
  14.      


    但很遗憾,<bean id="accessDeniedHandler" class="org.springframework.security.ui.AccessDeniedHandlerImpl">
这里尽管用了自定义的类,依然不起效果,依然出现access denied的页面,
没办法,只好依然用access-denied-page="/common/403.jsp">,只不过
在403.jsp中,用一个重定向,就可以重新定向到比如struts2.action去自由发挥拉

3 session超时
   spring security 3中提供了相关的配置设置,但可惜2中没有,
只有继续动手,首先,要在web.xml中,将自定义的filter放在spring security 2的
fiter前,比如
   

Java代码  收藏代码
  1.      <filter>    
  2.     <filter-name>SessionTimeoutFilter</filter-name>    
  3.     <filter-class>com.liao.security.SessionTimeoutFilter</filter-class>    
  4. </filter>    
  5. <filter-mapping>    
  6.     <filter-name>SessionTimeoutFilter</filter-name>    
  7.     <url-pattern>/*</url-pattern>    
  8. </filter-mapping>    



  然后代码中:
  

Java代码  收藏代码
  1. public class SessionTimeoutFilter implements Filter {  
  2.   
  3.     private String str;  
  4.     public void destroy() {  
  5.         // TODO Auto-generated method stub  
  6.   
  7.     }  
  8.   
  9.     public void doFilter(ServletRequest request, ServletResponse response,  
  10.             FilterChain chain) throws IOException, ServletException {  
  11.         HttpServletRequest servletRequest = (HttpServletRequest) request;  
  12.         HttpServletResponse servletResponse = (HttpServletResponse) response;  
  13.         HttpSession session = servletRequest.getSession();  
  14.   
  15.         String url = servletRequest.getRequestURI();  
  16.         String path = url.substring(url.lastIndexOf("/"));  
  17.   
  18.         if (path.indexOf("login.action") == -1 && path.indexOf(".action") != -1) {  
  19.   
  20.             if (session.getAttribute("userId") == null) {  
  21.                   
  22.                 str = "<script language='javascript'>alert('登录超时,请重新登录');"  
  23.                     + "window.top.location.href="+"'"+servletRequest.getContextPath()+"/login.action"+"';"+  
  24.   
  25.                     "</script>";  
  26.                   
  27.                 response.setContentType("text/html;charset=UTF-8");// 解决中文乱码  
  28.   
  29.                 try {  
  30.                     PrintWriter writer = response.getWriter();  
  31.   
  32.                     writer.write(str);  
  33.                     writer.flush();  
  34.                     writer.close();  
  35.   
  36.                 } catch (Exception e) {  
  37.   
  38.                 }  
  39.                   
  40.                   
  41.                             } else {  
  42.                 chain.doFilter(request, response);  
  43.             }  
  44.         } else {  
  45.             chain.doFilter(request, response);  
  46.         }  
  47.   
  48.     }  



  这里要判断,如果加载的不是login.action或者加载的不是.action结尾的(比如一些资源文件等)的,就要判断其中session是否null了,null的话跳转,
总体来说,功能就实现了

posted @ 2012-07-11 09:40  ctou45  阅读(476)  评论(0编辑  收藏  举报