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,并且同时要删除原先的:
- <ss:form-login login-page="/login.action"
- authentication-failure-url="/login.action?error=true"
- default-target-url="/" always-use-default-target="true" />
再来看下这个插入点:
- <bean id="authenticationProcessingFilterEntryPoint"
- class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
- <property name="loginFormUrl" value="/login.action" />
- <property name="forceHttps" value="false" />
- </bean>
接下来,建立自定义的类MyAuthenticationProcessingFilter,代码如下:
- ublic class MyAuthenticationProcessingFilter extends
- AuthenticationProcessingFilter {
- protected void onSuccessfulAuthentication(HttpServletRequest request,
- HttpServletResponse response, Authentication authResult)
- throws IOException {
- super.onSuccessfulAuthentication(request, response, authResult);
- Object obj = SecurityContextHolder.getContext().getAuthentication()
- .getPrincipal();
- if (obj instanceof UserDetails) {
- userId = ((UserInfo) obj).getUserid();
- username= ((UserInfo) obj).getUsername();
- }
- request.getSession().setAttribute("userId", userId);
- }
可以看到,继承了AuthenticationProcessingFilter就可以了,在
onSuccessfulAuthentication方法中,可以进行session的保存了!
接下来要在配置文件中进行配置,注册替换掉原来的,如下:
- <ss:logout logout-success-url="/login.action" />
- <ss:authentication-manager alias="authenticationManager" />
- <bean id="authenticationProcessingFilter"
- class="com.liao.security.MyAuthenticationProcessingFilter">
- <ss:custom-filter before="AUTHENTICATION_PROCESSING_FILTER" />
- <property name="defaultTargetUrl" value="/" />
- <property name="filterProcessesUrl" value="/j_spring_security_check" />
- <property name="authenticationFailureUrl" value="/login.action?error=true" />
- <property name="authenticationManager" ref="authenticationManager" />
- </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,
- <bean id="exceptionTranslationFilter"
- class="org.springframework.security.ui.ExceptionTranslationFilter">
- <property name="accessDeniedHandler" ref="accessDeniedHandler" />
- <property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint" />
- </bean>
- <!-- 处理AccessDeniedException -->
- <bean id="accessDeniedHandler" class="org.springframework.security.ui.AccessDeniedHandlerImpl">
- <property name="errorPage" value="/common/403.jsp" />
- </bean>
但很遗憾,<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前,比如
- <filter>
- <filter-name>SessionTimeoutFilter</filter-name>
- <filter-class>com.liao.security.SessionTimeoutFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>SessionTimeoutFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
然后代码中:
- public class SessionTimeoutFilter implements Filter {
- private String str;
- public void destroy() {
- // TODO Auto-generated method stub
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- HttpServletRequest servletRequest = (HttpServletRequest) request;
- HttpServletResponse servletResponse = (HttpServletResponse) response;
- HttpSession session = servletRequest.getSession();
- String url = servletRequest.getRequestURI();
- String path = url.substring(url.lastIndexOf("/"));
- if (path.indexOf("login.action") == -1 && path.indexOf(".action") != -1) {
- if (session.getAttribute("userId") == null) {
- str = "<script language='javascript'>alert('登录超时,请重新登录');"
- + "window.top.location.href="+"'"+servletRequest.getContextPath()+"/login.action"+"';"+
- "</script>";
- response.setContentType("text/html;charset=UTF-8");// 解决中文乱码
- try {
- PrintWriter writer = response.getWriter();
- writer.write(str);
- writer.flush();
- writer.close();
- } catch (Exception e) {
- }
- } else {
- chain.doFilter(request, response);
- }
- } else {
- chain.doFilter(request, response);
- }
- }
这里要判断,如果加载的不是login.action或者加载的不是.action结尾的(比如一些资源文件等)的,就要判断其中session是否null了,null的话跳转,
总体来说,功能就实现了