当前位置:   article > 正文

SpringSecurity 配置(登陆验证,session失效等等)

SpringSecurity 配置(登陆验证,session失效等等)

SpringSecurity 配置(登陆验证,session失效等等)

2015年09月28日 15:44:24 iteye_1371 阅读数:9 标签: security 更多

个人分类: spring_security

SpringSecurity安全配置—SSH整合
项目中使用了SpringSecurity,将SpringSecurity安全配置整理出来,实现SpringSecurity安全配置登陆,供需要的朋友参考
使用Springsecurity首先要提的就是jar包了,Springsecurity的jar下载地址:http://static.springsource.org/spring-security/site/downloads.html。不过我的项目里的jar包比较旧点了,是从项目抽取出来的,所需jar如下:

第1步:新建一个web工程,将Springsecurity的jar添加到web工程中WEB-INF中lib中,本DEMO中整合了Struts2,Hibernate,Spring,编写web.xml,具体配置如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.5"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  7. <!-- 加载Spring的配置文件 -->
  8. <context-param>
  9. <param-name>contextConfigLocation</param-name>
  10. <param-value>classpath:applicationContext*.xml</param-value>
  11. </context-param>
  12. <!-- 中文过滤器 -->
  13. <filter>
  14. <filter-name>chinese</filter-name>
  15. <filter-class>com.filter.EncodingFilter</filter-class>
  16. </filter>
  17. <!-- 检测是否登陆过滤器 -->
  18. <filter>
  19. <filter-name>loginFilter</filter-name>
  20. <filter-class>com.filter.LoginFilter</filter-class>
  21. <!-- sessionKey:需检查的在 Session 中保存的关键字 -->
  22. <init-param>
  23. <param-name>sessionKey</param-name>
  24. <param-value>LOGIN_NAME</param-value>
  25. </init-param>
  26. <!-- redirectURL:如果用户未登录,则重定向到指定的页面,URL不包括 ContextPath -->
  27. <init-param>
  28. <param-name>redirectURL</param-name>
  29. <param-value>/user/login.htm</param-value>
  30. </init-param>
  31. <!-- notCheckURLList:不做检查的URL列表,以分号分开,并且 URL 中不包括 ContextPath -->
  32. <init-param>
  33. <param-name>notCheckURLList</param-name>
  34. <param-value>/user/login.htm;/user/my.htm;</param-value>
  35. </init-param>
  36. </filter>
  37. <!-- 控制Session的开关 -->
  38. <filter>
  39. <filter-name>openSession</filter-name>
  40. <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
  41. </filter>



<!--
Spring security Filter(注意配置文件的Filter的位置,否则SpringSecurityUtils.getCurrentUser()出现空指针异常。)
在web.xml文件中加入Filter声明: 这个Filter会拦截所有的URL请求,并且对这些URL请求进行Spring Security的验证
注意:
1、springSecurityFilterChain这个名称是由命名空间默认创建的用于处理web安全的一个内部的bean的id。所以在Spring配置文件中,不应该再使用这个id作为你的bean。 
2、登录action:/spring_security_login
3、 登出action:j_spring_security_logout (这两个action是springSecurity自带的,直接用就可以了)
4、 Filter的配置,在项目中,跟struts2一起使用,filter的前后顺序有关系。Spring secutiry要放在struts2的前面,否则系统找不到security的action
5、 怎么获取用户信息:可以参考springside中的实现org.springside.modules.security.springsecurity.SpringSecurityUtils。具体信息都在Authentication这个类中。

  1. -->
  2. <filter>
  3. <filter-name>springSecurityFilterChain</filter-name>
  4. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  5. </filter>
  6. <!-- Struts2配置 -->
  7. <filter>
  8. <filter-name>struts2</filter-name>
  9. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  10. </filter>
  11. <filter-mapping>
  12. <filter-name>chinese</filter-name>
  13. <url-pattern>/*</url-pattern>
  14. </filter-mapping>
  15. <filter-mapping>
  16. <filter-name>openSession</filter-name>
  17. <url-pattern>/*</url-pattern>
  18. </filter-mapping>
  19. <filter-mapping>
  20. <filter-name>springSecurityFilterChain</filter-name>
  21. <url-pattern>/*</url-pattern>
  22. </filter-mapping>
  23. <filter-mapping>
  24. <filter-name>loginFilter</filter-name>
  25. <url-pattern>*.htm</url-pattern>
  26. </filter-mapping>
  27. <filter-mapping>
  28. <filter-name>struts2</filter-name>
  29. <url-pattern>*.htm</url-pattern>
  30. </filter-mapping>
  31. <!-- Spring的监听器 -->
  32. <listener>
  33. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  34. </listener>
  35. <welcome-file-list>
  36. <welcome-file>index.jsp</welcome-file>
  37. </welcome-file-list>
  38. </web-app>



第2步:编写LoginFilter.java,用于过滤校验用户是否登陆,具体如下:

  1. /**
  2. * @Discription: 登陆过滤器:
  3. * 用于检测用户是否登陆的过滤器,如果未登录,则重定向到指的登录页面
  4. * 配置参数:
  5. * sessionKey:需检查的在 Session 中保存的关键字
  6. * redirectURL:如果用户未登录,则重定向到指定的页面,URL不包括 ContextPath
  7. * notCheckURLList:不做检查的URL列表,以分号分开,并且 URL 中不包括 ContextPath
  8. * @Project: SpringSecurity
  9. * @Package: com.filter
  10. * @Title: LoginFilter.java
  11. * @author: [heyong]
  12. * @date 2012-4-21
  13. * @version 1.0
  14. * @update [日期YYYY-MM-DD] [更改人姓名]
  15. */
  16. public class LoginFilter implements Filter{
  17. /**
  18. * <p>Discription:[logger日志]</p>
  19. */
  20. private static Log logger = LogFactory.getLog(LoginFilter.class);
  21. /**
  22. * <p>Discription:[需检查的在 Session 中保存的关键字]</p>
  23. */
  24. private String sessionKey = null;
  25. /**
  26. * <p>Discription:[如果用户未登录,则重定向到指定的页面,URL不包括 ContextPath ]</p>
  27. */
  28. private String redirectURL = null;
  29. /**
  30. * <p>Discription:[不做检查的URL列表,以分号分开,并且 URL 中不包括 ContextPath]</p>
  31. */
  32. private List<String> notCheckURLList = new ArrayList<String>();
  33. public void destroy() {
  34. notCheckURLList.clear();
  35. }
  36. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {
  37. HttpServletRequest request = (HttpServletRequest) servletRequest;
  38. HttpServletResponse response = (HttpServletResponse) servletResponse;
  39. // 获得Session
  40. HttpSession session = request.getSession();
  41. // 判断sessionKey 是否为空
  42. if(StringUtils.isEmpty(sessionKey)){
  43. filterChain.doFilter(request, response);
  44. return;
  45. }
  46. if (!checkRequestURIIntNotFilterList(request)) {
  47. UserDetail userDetail = null;
  48. try {
  49. // 取得当前用户登陆的信息
  50. userDetail = (UserDetail)SpringSecurityUtils.getCurrentUser();
  51. } catch (Exception e) {
  52. logger.info("Event=[LoginFilter#doFilter] redirect:".concat(request.getContextPath().concat(redirectURL)));
  53. response.sendRedirect(request.getContextPath().concat(redirectURL));
  54. return;
  55. }
  56. // 判断是否登陆
  57. if (userDetail == null || userDetail.getUserId() == null) {
  58. response.sendRedirect(request.getContextPath().concat(redirectURL));
  59. return;
  60. }
  61. // 在userDetail中得到用户信息
  62. SysStUser user = userDetail.getCurrentUser();
  63. // UserDetail 存在,测检查Session是否存在,若不存在则,初始化Session
  64. if (session.getAttribute(sessionKey) == null) {
  65. logger.info("Event=[LoginFilter#doFilter] sessionKey: " + sessionKey);
  66. session.setAttribute(sessionKey, user);
  67. }
  68. }
  69. filterChain.doFilter(servletRequest, servletResponse);
  70. }
  71. public void init(FilterConfig filterConfig) throws ServletException {
  72. sessionKey = filterConfig.getInitParameter("sessionKey");
  73. redirectURL = filterConfig.getInitParameter("redirectURL");
  74. String urlList = filterConfig.getInitParameter("notCheckURLList");
  75. if (StringUtils.isNotEmpty(urlList)) {
  76. StringTokenizer st = new StringTokenizer(urlList, ";");
  77. notCheckURLList.clear();
  78. while (st.hasMoreTokens()) {
  79. notCheckURLList.add(st.nextToken());
  80. }
  81. }
  82. }
  83. /**
  84. * @Description: 检测当前访问URL,是否有过滤掉的URL。
  85. * @author [heyong]
  86. * @date 2012-4-21
  87. * @version 1.0
  88. * @param request
  89. * @return
  90. * @update:[日期YYYY-MM-DD] [更改人姓名]
  91. */
  92. private boolean checkRequestURIIntNotFilterList(HttpServletRequest request) {
  93. String url = request.getServletPath() + (request.getPathInfo() == null ? "" : request.getPathInfo());
  94. return notCheckURLList.contains(url);
  95. }
  96. }
  97. 3步:提供一个UserDetail.java,该类继承org.springframework.security.userdetails.User类,用于保存一些自定义的业务数据,具体如下:
  98. /**
  99. * @Discription: UserDetail继承User
  100. * @Project: SpringSecurity
  101. * @Package: com.security
  102. * @Title: UserDetail.java
  103. * @author: [heyong]
  104. * @date 2012-4-21
  105. * @version 1.0
  106. * @update [日期YYYY-MM-DD] [更改人姓名]
  107. */
  108. public class UserDetail extends User {
  109. /**
  110. * <p>Discription:[serialVersionUID]</p>
  111. */
  112. private static final long serialVersionUID = 5533186529087001787L;
  113. /**
  114. * 用户ID
  115. */
  116. private String userId;
  117. /**
  118. * 用户真实姓名
  119. */
  120. private String realName;
  121. /**
  122. * 当前登录的用户信息
  123. */
  124. private SysStUser currentUser;
  125. public UserDetail(String userId, String realName, String username,String password, GrantedAuthority[] authorities) {
  126. super(username, password, true, true, true, true, authorities);
  127. this.userId = userId;
  128. this.realName = realName;
  129. }
  130. public UserDetail(String username, String password, boolean enabled,
  131. boolean accountNonExpired, boolean credentialsNonExpired,
  132. boolean accountNonLocked, GrantedAuthority[] authorities)throws IllegalArgumentException {
  133. super(username, password, enabled, accountNonExpired,credentialsNonExpired, accountNonLocked, authorities);
  134. }
  135. public String getUserId() {
  136. return userId;
  137. }
  138. public void setUserId(String userId) {
  139. this.userId = userId;
  140. }
  141. public String getRealName() {
  142. return realName;
  143. }
  144. public void setRealName(String realName) {
  145. this.realName = realName;
  146. }
  147. public SysStUser getCurrentUser() {
  148. return currentUser;
  149. }
  150. public void setCurrentUser(SysStUser currentUser) {
  151. this.currentUser = currentUser;
  152. }
  153. }


第4步:提供一个UserDetailsServiceImpl.java,该类实现org.springframework.security.userdetails.UserDetailsService类,必须实现loadUserByUsername()方法,具体如下:

  1. /**
  2. * @Discription: UserDetailsServiceImpl实现UserDetailsService接口,实现UserDetailsService类中loadUserByUsername()方法
  3. * @Project: SpringSecurity
  4. * @Package: com.iservices
  5. * @Title: UserDetailsServiceImpl.java
  6. * @author: [heyong]
  7. * @date 2012-4-20
  8. * @version 1.0
  9. * @update [日期YYYY-MM-DD] [更改人姓名]
  10. */
  11. public class UserDetailsServiceImpl implements UserDetailsService{
  12. /**
  13. * 用户信息Services(自已提供查询Services查询接口)
  14. */
  15. private UsersServices usersServices;
  16. /**
  17. * @Description: 实现loadUserByUsername(),根据用户名明查询用户的信息
  18. * @author [heyong]
  19. * @date 2012-4-20
  20. * @version 1.0
  21. * @param LoginName:登陆用户名
  22. * @return
  23. * @throws UsernameNotFoundException
  24. * @throws DataAccessException
  25. * @update:[日期YYYY-MM-DD] [更改人姓名]
  26. */
  27. public UserDetails loadUserByUsername(String LoginName)throws UsernameNotFoundException, DataAccessException {
  28. SysStUser sysStUser = usersServices.searchSysUserByLoginName(LoginName);
  29. if (sysStUser != null) {
  30. UserDetail userdetail = new UserDetail(sysStUser.getId(), sysStUser.getUserRname(),sysStUser.getUserName(),sysStUser.getUserPwd(),new GrantedAuthority[0]);
  31. userdetail.setCurrentUser(sysStUser);
  32. return userdetail;
  33. }
  34. return null;
  35. }
  36. public void setUsersServices(UsersServices usersServices) {
  37. this.usersServices = usersServices;
  38. }
  39. }


第5步:提供一个ResourceDetailsServiceImpl.java,该类实现org.springside.modules.security.springsecurity.ResourceDetailsService类,必须实现getRequestMap()方法,具体如下:
/**
* 从数据库查询URL--授权定义Map的实现类.
*/
public class ResourceDetailsServiceImpl implements ResourceDetailsService {
public LinkedHashMap<String, String> getRequestMap() throws Exception {
return new LinkedHashMap<String, String>();
}
}

第6步:前面基础的java实现类都已将准备完成了,接下来重要的一步来了。在web工程的src目录下新建一个applicationContext-security.xml,用于SpringSecurity安全配置,具体如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:s="http://www.springframework.org/schema/security"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  5. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"
  6. default-autowire="byType" default-lazy-init="true">
  7. <description>SpringSecurity安全配置</description>
  8. <!--
  9. http安全配置:
  10. 1、default-target-url:默认的目标路劲,指定登陆成功,跳转的页面
  11. 2、authentication-failure-url:指定登陆失败,跳转页面
  12. 3、logout-success-url:登录成功后,退出,跳转URL
  13. -->
  14. <s:http auto-config="true" access-decision-manager-ref="accessDecisionManager">
  15. <s:form-login login-page="/webapp/login.jsp" default-target-url="/user/queryUsersAll.htm" authentication-failure-url="/user/login.htm?error=true" />
  16. <s:logout logout-success-url="/user/login.htm" invalidate-session="true"/>
  17. <s:remember-me key="e37f4b31-0c45-11dd-bd0b-0800200c9a66" />
  18. </s:http>
  19. <!-- 认证配置认证管理器。用户名密码都集成在配置文件中 -->
  20. <s:authentication-provider user-service-ref="userDetailsService">
  21. <!-- 可设置hash使用sha1或md5散列密码后再存入数据库 -->
  22. <s:password-encoder hash="plaintext" />
  23. </s:authentication-provider>
  24. <!-- 项目实现的用户查询服务(第4步提供的UserDetailsServiceImpl.java类) -->
  25. <bean id="userDetailsService" class="com.security.UserDetailsServiceImpl">
  26. <property name="usersServices" ref="usersServicesImpl"></property>
  27. </bean>
  28. <!-- 重新定义的FilterSecurityInterceptor,使用databaseDefinitionSource提供的url-授权关系定义 -->
  29. <bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
  30. <s:custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
  31. <property name="accessDecisionManager" ref="accessDecisionManager" />
  32. <property name="objectDefinitionSource" ref="databaseDefinitionSource" />
  33. </bean>
  34. <!-- DefinitionSource工厂,使用resourceDetailsService提供的URL-授权关系. -->
  35. <bean id="databaseDefinitionSource" class="org.springside.modules.security.springsecurity.DefinitionSourceFactoryBean">
  36. <property name="resourceDetailsService" ref="resourceDetailsService" />
  37. </bean>
  38. <!-- 项目实现的URL-授权查询服务(第5步提供的ResourceDetailsServiceImpl.java类) -->
  39. <bean id="resourceDetailsService" class="com.security.ResourceDetailsServiceImpl" />
  40. <!-- 授权判断配置, 将授权名称的默认前缀由ROLE_改为A_. -->
  41. <bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
  42. <property name="decisionVoters">
  43. <list>
  44. <bean class="org.springframework.security.vote.RoleVoter">
  45. <property name="rolePrefix" value="A_" />
  46. </bean>
  47. <bean class="org.springframework.security.vote.AuthenticatedVoter" />
  48. </list>
  49. </property>
  50. </bean>


</beans>
到此为止,基本的java类,以及配置,都已完成。
第5步:准备测试jsp页面,login.jsp,具体如下:

  1. <body>
  2. <CENTER>
  3. <h2>用户登陆-SpringSecurity安全配置Demo</h2>
  4. <form method="post" id="loginForm" class="login-form" action="/j_spring_security_check" >
  5. <div class="bg-login-error" <c:if test="${empty SPRING_SECURITY_LAST_EXCEPTION}">style='display:none;'</c:if>>
  6. 用户名或密码错误。
  7. </div>
  8. 用户名:
  9. <input id="j_username" type="text" tabindex="1" name="j_username" value=""/><br/>
  10. 密 码:
  11. <input id="j_password" type="password" tabindex="1" name="j_password" value=""/><br/>
  12. <button type="submit">登 录</button>
  13. <button type="reset">重 置</button>
  14. </form>
  15. </CENTER>
  16. </body>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/131865?site
推荐阅读
相关标签
  

闽ICP备14008679号