最近在研究SpringSecurity开始一切正常但是自定义过滤器后却发现对Session控制的会话控制失效了。网上说如果重写了User类要重写equals和hashCode方法。但是我没有重写User类也不好使,之后我重写了后也重写了equals和hashCode方法,还是不好使。调试之后根本没有进入equals方法但是hashCode方法却走了很多遍。求大神指点。下面开帖代码。 <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <!-- 访问被拒绝时跳转到403界面 --> <http entry-point-ref="authenticationProcessingFilterEntryPoint" access-denied-page="/403.jsp" > <!-- 放行页面 --> <intercept-url pattern="/*.css" filters="none" /> <intercept-url pattern="/error.jsp" filters="none" /> <intercept-url pattern="/index*.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="any" /> <!-- 访问全部要通过身份验证 --> <intercept-url pattern="/**" access="isAuthenticated()" /> <!-- 访问全部要有ROLE_USER权限 --> <intercept-url pattern="/**" access="ROLE_USER" /> <!-- 安全退出后的页面 --> <logout logout-success-url="/logout.jsp" /> <!-- 两周内记住我 --> <remember-me key="jbcpPetStore" /> <!-- 检测失效的sessionId,超时时定位到另外一个URL, --> <session-management session-authentication-error-url="/No_certification.jsp" invalid-session-url="/index.jsp" session-fixation-protection="migrateSession"> <!-- 防止多端登录 --> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/error.jsp" /> </session-management> <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" /> </http> <!-- 自定义登录过滤 --> <beans:bean id="loginFilter" class="filter.UsernamePasswordAuthenticationExtendFilter"> <!-- 验证页面 --> <beans:property name="filterProcessesUrl" value="/j_spring_security_check" /> <!-- 验证成功后的处理 --> <beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler" /> <!-- 验证失败后的处理 --> <beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler" /> <!-- 认证器 --> <beans:property name="authenticationManager" ref="authenticationManager" /> </beans:bean> <!-- 认证器 --> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref=""myUserDetailsService"" /> </authentication-manager> <!-- 注入认证器 --> <beans:bean id="myUserDetailsService" class="filter.MyUserDetailService" /> <!-- 开始注入登录过滤器 --> <beans:bean id="loginLogAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <beans:property name="defaultTargetUrl" value="/welcome.jsp"></beans:property> </beans:bean> <beans:bean id="simpleUrlAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <beans:property name="defaultFailureUrl" value="/index.jsp?error=true"></beans:property> </beans:bean> <!-- 注入登录过滤器结束 --> <beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <beans:property name="loginFormUrl" value="/index.jsp"></beans:property> </beans:bean> </beans:beans> web.xml页面 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 防止请求Spring乱码 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <!--强制转换编码(request和response均适用) --> <param-name>ForceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring Security过滤器 --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Struts2 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> <!-- Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:applicationContext-security.xml</param-value> </context-param> <!-- Spring监听 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 监听session 防止多端登录 --> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener> <!-- session有效期为30分 --> <session-config> <session-timeout>30</session-timeout> </session-config> </web-app> |
|
继承UsernamePasswordAuthenticationFilter类的代码
package filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; /** * 重载SECURITY3的UsernamePasswordAuthenticationFilter的attemptAuthentication, * obtainUsername,obtainPassword方法(完善逻辑) 增加验证码校验模块 添加验证码属性 添加验证码功能开关属性 * * @author shadow * @email 124010356@qq.com * @create 2012.04.28 */ public class UsernamePasswordAuthenticationExtendFilter extends UsernamePasswordAuthenticationFilter { private SessionAuthenticationStrategy sessionAuthenticationStrategy = null; public SessionAuthenticationStrategy getSessionAuthenticationStrategy() { return sessionAuthenticationStrategy; } public void setSessionAuthenticationStrategy( SessionAuthenticationStrategy sessionAuthenticationStrategy) { this.sessionAuthenticationStrategy = sessionAuthenticationStrategy; } // 验证码字段 private String validateCodeParameter = "validateCode"; // 是否开启验证码功能 private boolean openValidateCode = false; @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { request.getSession().removeAttribute("msg"); // 只接受POST方式传递的数据 if (!"POST".equals(request.getMethod())){ throw new AuthenticationServiceException("不支持非POST方式的请求!"); } // 开启验证码功能的情况 if (isOpenValidateCode()){ checkValidateCode(request); } // 获取Username和Password String username = obtainUsername(request); String password = obtainPassword(request); // UsernamePasswordAuthenticationToken实现Authentication校验 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); // 允许子类设置详细属性 setDetails(request, authRequest); // 运行UserDetailsService的loadUserByUsername 再次封装Authentication return this.getAuthenticationManager().authenticate(authRequest); } // 匹对验证码的正确性 public void checkValidateCode(HttpServletRequest request) { String jcaptchaCode = obtainValidateCodeParameter(request); if (null == jcaptchaCode || "".equals(jcaptchaCode)){ throw new AuthenticationServiceException("请输入验证码"); } if(null == request.getSession().getAttribute("rand")){ throw new AuthenticationServiceException("验证码失效"); } //对比普通验证码 if(!request.getSession().getAttribute("rand").equals(jcaptchaCode)){ throw new AuthenticationServiceException("验证码错误!"); } return; } public String obtainValidateCodeParameter(HttpServletRequest request) { Object obj = request.getParameter(getValidateCodeParameter()); return null == obj ? "" : obj.toString().trim(); } @Override protected String obtainUsername(HttpServletRequest request) { Object obj = request.getParameter(getUsernameParameter()); return null == obj ? "" : obj.toString().trim(); } @Override protected String obtainPassword(HttpServletRequest request) { Object obj = request.getParameter(getPasswordParameter()); return null == obj ? "" : obj.toString().trim(); } public String getValidateCodeParameter() { return validateCodeParameter; } public void setValidateCodeParameter(String validateCodeParameter) { this.validateCodeParameter = validateCodeParameter; } public boolean isOpenValidateCode() { return openValidateCode; } public void setOpenValidateCode(boolean openValidateCode) { this.openValidateCode = openValidateCode; } } UserDetailsService页面代码 package filter; import java.util.ArrayList; import java.util.Collection; import model.UserDetail; import org.springframework.dao.DataAccessException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; /** * 登录类 * * @author Administrator * @comment 在这个类中,你就可以从数据库中读入用户的密码、角色信息、是否锁定、 账号是否过期等. new User()方法参数说明, String * username(用户名), String password(密码), boolean enabled(账户是否可用), boolean * accountNonExpired(账户是否未过期), boolean accountNonLocked(账户是否未锁定), * Collection<GrantedAuthority> authorities(账户所受权限). */ public class MyUserDetailService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(); GrantedAuthorityImpl auth2 = new GrantedAuthorityImpl("ROLE_USER");// 进行授权 auths.add(auth2);// 添加所授的权限 UserDetail user = new UserDetail("123", "123", true, true, true, true, auths); return user; } } UserDetail类方法 package model; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; @SuppressWarnings("serial") public class UserDetail implements UserDetails { private Collection<GrantedAuthority> authorities; private String password; private String username; private boolean isAccountNonExpired; private boolean isAccountNonLocked; private boolean isCredentialsNonExpired; private boolean isEnabled; /** default constructor */ public UserDetail() { } public UserDetail(String username, String password, boolean isAccountNonExpired, boolean isAccountNonLocked, boolean isCredentialsNonExpired, boolean isEnabled, Collection<GrantedAuthority> authorities) { this.username = username; this.password = password; this.isAccountNonExpired = isAccountNonExpired; this.isAccountNonLocked = isAccountNonLocked; this.isCredentialsNonExpired = isCredentialsNonExpired; this.isEnabled = isEnabled; this.authorities = authorities; } // Constructors public Collection<GrantedAuthority> getAuthorities() { return authorities; } public void setAuthorities(Collection<GrantedAuthority> authorities) { this.authorities = authorities; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public boolean isAccountNonExpired() { return isAccountNonExpired; } public void setAccountNonExpired(boolean isAccountNonExpired) { this.isAccountNonExpired = isAccountNonExpired; } public boolean isAccountNonLocked() { return isAccountNonLocked; } public void setAccountNonLocked(boolean isAccountNonLocked) { this.isAccountNonLocked = isAccountNonLocked; } public boolean isCredentialsNonExpired() { return isCredentialsNonExpired; } public void setCredentialsNonExpired(boolean isCredentialsNonExpired) { this.isCredentialsNonExpired = isCredentialsNonExpired; } public boolean isEnabled() { return isEnabled; } public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } @Override public boolean equals(Object obj) { System.out.println("进入equals方法"); if (obj instanceof UserDetail) { UserDetail another = (UserDetail)obj; return this.getUsername().equals(another.getUsername()); } return super.equals(obj); } @Override public int hashCode() { System.out.println("进入hashCode方法"); return this.getUsername().hashCode(); } } |
|
自顶!
|
|
人工置顶!
|
|
大神们呢??
不要沉啊!! |
|
人工置顶!
|