当前位置:   article > 正文

Spring Security3 自定义登录,验证码登录_spring-security.xml 验证码 和配置类

spring-security.xml 验证码 和配置类

Security3 安全架构 这里主要说的就是spring-security.xml 配置 因为网上这个资料确实很少

首先 pom  

org.springframework.security 的包 我现在版本是3.1.4的  注意依赖都要导入的 包名就不写了!

web.xml

security 的过滤器链

  1. <filter>
  2. <filter-name>springSecurityFilterChain</filter-name>
  3. <filter-class>
  4. org.springframework.web.filter.DelegatingFilterProxy
  5. </filter-class>
  6. </filter>
  7. <filter-mapping>
  8. <filter-name>springSecurityFilterChain</filter-name>
  9. <url-pattern>/*</url-pattern>
  10. </filter-mapping>

现在开始正题

spring-security.xml 配置  这个配置主要是用来重写attemptAuthentication方法的 这个是重点

  1. <http auto-config="true" use-expressions="true" access-denied-page="/403.jsp" >
  2. <!--login-processing-url 参数为登录的提交请求url -->
  3. <form-login login-processing-url="/home" login-page="/doctorLogin" always-use-default-target="false" default-target-url="/"/>
  4. <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
  5. <logout invalidate-session="true" logout-success-url="/doctorLogin" logout-url="/logout"/> <!--退出登录-->
  6. <custom-filter before="FORM_LOGIN_FILTER" ref="verificationLogin"></custom-filter> <!--自定义拦截器 before 之前 FORM_LOGIN_FILTER 登录拦截-->
  7. <session-management>
  8. <concurrency-control max-sessions="1" error-if-maximum-exceeded="false" expired-url="/doctorLogin?error=2"/><!--只允许单线登录-->
  9. </session-management>
  10. </http>
  11. <beans:bean id="verificationLogin" class="com.hearing.cloud.background.loginFilter.LoginFilterAuthentication"> <!--登录拦截器-->
  12. <beans:property name="authenticationManager" ref="authenticationManager"/> <!--身份验证 必须的-->
  13. <beans:property name="authenticationSuccessHandler" ref="SuccessHandler" /> <!--验证通过 必须的-->
  14. <beans:property name="authenticationFailureHandler" ref="FailureHandler" /> <!--验证失败 必须的-->
  15. </beans:bean>
  16. <authentication-manager alias="authenticationManager"> <!--身份验证-->
  17. <authentication-provider user-service-ref="userDaoImpl"> <!--用户数据查询-->
  18. </authentication-provider>
  19. </authentication-manager>
  20. <beans:bean id="SuccessHandler" class="com.hearing.cloud.background.loginFilter.LoginSuccessHandler"></beans:bean> <!--验证通过逻辑-->
  21. <beans:bean id="FailureHandler" class="com.hearing.cloud.background.loginFilter.LoginFailureHandler"></beans:bean> <!--验证失败逻辑-->

   //UsernamePasswordAuthenticationFilter的实现 重写 attemptAuthentication方法 逻辑随意修改

  1. package com.hearing.cloud.background.loginFilter;
  2. import com.hearing.cloud.background.model.OrdinaryUser;
  3. import com.hearing.cloud.background.model.User;
  4. import com.hearing.cloud.background.service.IOrdinaryUserManager;
  5. import com.hearing.cloud.background.service.IUserManager;
  6. import com.hearing.cloud.background.util.ActionUtil;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.security.authentication.AuthenticationServiceException;
  9. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  10. import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
  11. import org.springframework.security.core.Authentication;
  12. import org.springframework.security.core.AuthenticationException;
  13. import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
  14. import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
  15. import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
  16. import org.springframework.util.Assert;
  17. import javax.servlet.http.HttpServletRequest;
  18. import javax.servlet.http.HttpServletResponse;
  19. import java.util.Map;
  20. //这里一般都是继承UsernamePasswordAuthenticationFilter 但是 我这里没有继承他 我继承了他爷爷 AbstractAuthenticationProcessingFilter
  21. public class LoginFilterAuthentication extends AbstractAuthenticationProcessingFilter {
  22. public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
  23. public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
  24. /** @deprecated */
  25. @Deprecated
  26. public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
  27. private String usernameParameter = "j_username";
  28. private String passwordParameter = "j_password";
  29. private boolean postOnly = true;
  30. private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();
  31. //继承爷爷的原因是 我重新构造这个参数, 默认的是 /j_spring_security_check 我认为太丑
  32. public LoginFilterAuthentication() {
  33. super("/home");
  34. }
  35. @Autowired
  36. private IOrdinaryUserManager ordinaryUserManager;
  37. @Autowired
  38. private IUserManager iUserManager;
  39. @Autowired
  40. private ShaPasswordEncoder shaPasswordEncoder;
  41. public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
  42. if (this.postOnly &&!request.getMethod().equals("POST")) {
  43. throw new AuthenticationServiceException(
  44. "Authentication method not supported: " + request.getMethod());
  45. }
  46. UsernamePasswordAuthenticationToken authRequest=null;
  47. //前端的选择,0是用户名登录, 1是验证码登录
  48. Map<String,String> map = ActionUtil.getParameters(request);
  49. String selects=map.get("selects");
  50. if("0".equals(selects)){ //正常登陆 因为我们没有在xml中配置加密,所以我们手动加密,更灵活一些
  51. authRequest = new UsernamePasswordAuthenticationToken(账号, 密码);
  52. }else{ //电话号码登录 密码就不用加密了 直接登录
  53. //验证码对比结果
  54. boolean falg=true;
  55. if(falg) { //验证通过
  56. authRequest = new UsernamePasswordAuthenticationToken(账号, 密码);
  57. }else{//验证失败 我们要手动抛出一个异常,在后面的验证失败类中去捕获
  58. authRequest = new UsernamePasswordAuthenticationToken("", "");
  59. throw new AuthenticationServiceException("验证码错误");
  60. }
  61. request.getSession().removeAttribute("phone");
  62. }
  63. // Allow subclasses to set the "details" property
  64. setDetails(request, authRequest);
  65. // 执行校验(使用DaoAuthenticationProvider进行校验)
  66. return this.getAuthenticationManager().authenticate(authRequest);
  67. }
  68. protected String obtainPassword(HttpServletRequest request) {
  69. return request.getParameter(this.passwordParameter);
  70. }
  71. protected String obtainUsername(HttpServletRequest request) {
  72. return request.getParameter(this.usernameParameter);
  73. }
  74. protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
  75. authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
  76. }
  77. public void setUsernameParameter(String usernameParameter) {
  78. Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
  79. this.usernameParameter = usernameParameter;
  80. }
  81. public void setPasswordParameter(String passwordParameter) {
  82. Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
  83. this.passwordParameter = passwordParameter;
  84. }
  85. public void setPostOnly(boolean postOnly) {
  86. this.postOnly = postOnly;
  87. }
  88. }

   //查询用户的实现 实现 UserDetailsService的 loadUserByUsername方法 返回一个UserDetails  

  1. @Repository(value = "userDaoImpl")
  2. public class UserDaoImpl extends GenericDaoHibernate<User, String> implements IUserDao, UserDetailsService {
  3. /**
  4. * 用户登录
  5. */
  6. @SuppressWarnings({"deprecation", "rawtypes"})
  7. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
  8. {
  9. //逻辑我就不写了 你们想怎么写就怎么写,记得查询出来的 user 转换成 UserDetails
  10. }
  11. }

 

  //验证成功的方法 需要继承SimpleUrlAuthenticationSuccessHandler和实现AuthenticationSuccessHandler接口

  1. package com.hearing.cloud.background.loginFilter;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.security.core.Authentication;
  4. import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
  5. import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
  6. import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
  7. import org.springframework.security.web.savedrequest.RequestCache;
  8. import org.springframework.security.web.savedrequest.SavedRequest;
  9. import org.springframework.util.StringUtils;
  10. import javax.servlet.ServletException;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13. import java.io.IOException;
  14. public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
  15. //我重写的目的 1.主要是这个位置 因为我要访问我的 跳转首页方法的逻辑接口
  16. //2.是如果不改这里 登录会有两个后果,1.登录后关闭页面,在次打开,页面会显示路径无法加载,2.
  17. //第一次登录成功跳转页面是你首页加载的第一个js页面而不是首页,请认真对待
  18. @Value("/")
  19. private String defaultTargetUrl;
  20. private RequestCache requestCache = new HttpSessionRequestCache();
  21. @Override
  22. public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
  23. SavedRequest savedRequest = this.requestCache.getRequest(request, response);
  24. if(savedRequest == null) {
  25. super.onAuthenticationSuccess(request, response, authentication);
  26. } else {
  27. String targetUrlParameter = this.getTargetUrlParameter();
  28. if(!this.isAlwaysUseDefaultTargetUrl() && (targetUrlParameter == null || !StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
  29. this.clearAuthenticationAttributes(request);
  30. this.logger.debug("Redirecting to DefaultSavedRequest Url: " + defaultTargetUrl);
  31. this.getRedirectStrategy().sendRedirect(request, response, defaultTargetUrl);
  32. } else {
  33. this.requestCache.removeRequest(request, response);
  34. super.onAuthenticationSuccess(request, response, authentication);
  35. }
  36. }
  37. }
  38. public void setRequestCache(RequestCache requestCache) {
  39. this.requestCache = requestCache;
  40. }
  41. }

 //验证失败  需要实现AuthenticationFailureHandler 接口

  1. package com.hearing.cloud.background.loginFilter;
  2. import org.springframework.security.core.AuthenticationException;
  3. import org.springframework.security.web.DefaultRedirectStrategy;
  4. import org.springframework.security.web.RedirectStrategy;
  5. import org.springframework.security.web.authentication.AuthenticationFailureHandler;
  6. import org.springframework.security.web.util.UrlUtils;
  7. import org.springframework.util.Assert;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import javax.servlet.http.HttpSession;
  12. import java.io.IOException;
  13. public class LoginFailureHandler implements AuthenticationFailureHandler {
  14. private String defaultFailureUrl;
  15. private boolean forwardToDestination = false;
  16. private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
  17. private boolean allowSessionCreation = true;
  18. public LoginFailureHandler() {
  19. }
  20. public LoginFailureHandler(String defaultFailureUrl) {
  21. this.setDefaultFailureUrl(defaultFailureUrl);
  22. }
  23. public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
  24. if(this.defaultFailureUrl == null) {
  25. if("验证码错误".equals(e.getMessage())){
  26. redirectStrategy.sendRedirect(request, response, "/doctorLogin?error=3");
  27. }else{
  28. redirectStrategy.sendRedirect(request, response, "/doctorLogin?error=1");
  29. }
  30. } else {
  31. this.saveException(request, e);
  32. if(this.forwardToDestination) {
  33. request.getRequestDispatcher(this.defaultFailureUrl).forward(request, response);
  34. } else {
  35. this.redirectStrategy.sendRedirect(request, response, this.defaultFailureUrl);
  36. }
  37. }
  38. }
  39. public void setDefaultFailureUrl(String defaultFailureUrl) {
  40. Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultFailureUrl), "\'" + defaultFailureUrl + "\' is not a valid redirect URL");
  41. this.defaultFailureUrl = defaultFailureUrl;
  42. }
  43. protected final void saveException(HttpServletRequest request, AuthenticationException exception) {
  44. if(this.forwardToDestination) {
  45. request.setAttribute("SPRING_SECURITY_LAST_EXCEPTION", exception);
  46. } else {
  47. HttpSession session = request.getSession(false);
  48. if(session != null || this.allowSessionCreation) {
  49. request.getSession().setAttribute("SPRING_SECURITY_LAST_EXCEPTION", exception);
  50. }
  51. }
  52. }
  53. protected boolean isUseForward() {
  54. return this.forwardToDestination;
  55. }
  56. public void setUseForward(boolean forwardToDestination) {
  57. this.forwardToDestination = forwardToDestination;
  58. }
  59. protected boolean isAllowSessionCreation() {
  60. return this.allowSessionCreation;
  61. }
  62. public void setAllowSessionCreation(boolean allowSessionCreation) {
  63. this.allowSessionCreation = allowSessionCreation;
  64. }
  65. }
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号