javascript
Spring Security-- 验证码功能的实现
簡介
在spring security的內置login處理是無法滿足要求的,需要自己進行各種定制。這里介紹login中實現驗證碼的實現。
實現方法
可以有三種方法可以實現驗證碼的功能
第一種
自定義一個filter,放在SpringSecurity過濾器之前,在用戶登錄的時候會先經過這個filter,然后在這個filter中實現對驗證碼進行驗證的功能,這種方法不推薦,因為它已經脫離了SpringSecurity
第二種
自定義一個filter讓它繼承自UsernamePasswordAuthenticationFilter,然后重寫attemptAuthentication方法在這個方法中實現驗證碼的功能,如果驗證碼錯誤就拋出一個繼承自AuthenticationException的驗證嗎錯誤的異常比如(CaptchaException),然后這個異常就會被SpringSecurity捕獲到并將異常信息返回到前臺,這種實現起來比較簡單。
@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String requestCaptcha = request.getParameter(this.getCaptchaFieldName()); String genCaptcha = (String)request.getSession().getAttribute("code"); logger.info("開始校驗驗證碼,生成的驗證碼為:"+genCaptcha+" ,輸入的驗證碼為:"+requestCaptcha); if( !genCaptcha.equals(requestCaptcha)){ throw new CaptchaException( this.messageSource.getMessage("AbstractUserDetailsAuthenticationProvider.badCaptcha",null,"Default",null)); } return super.attemptAuthentication(request, response); }接著在配置文件中配置:
<bean id="loginFilter" class="com.zrhis.system.security.DefaultUsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"></property> <property name="authenticationSuccessHandler"> <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <property name="defaultTargetUrl" value="/index.jsp"></property> </bean> </property> <property name="authenticationFailureHandler"> <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login.jsp"></property> </bean> </property> </bean>最后在http中加入custom-filter配置,將這個filter放在SpringSecurity的FORM_LOGIN_FILTER之前.
<custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER"/>第三種
直接替換掉SpringSecurity的UsernamePasswordAuthenticationFilter,這種比較復雜,但是更為合理,也是我現在正在用的。
如果用這種方法那么http 中的auto-config就必須去掉,而form-login配置也必須去掉,因為這個不需要了,里面的屬性都需要我們自行注入。
首先需要創建并配置一個login.jsp作為登錄頁面EntryPoint
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <property name="loginFormUrl" value="/login.jsp" /> </bean>然后在http中配置下
<sec:http access-decision-manager-ref="accessDecisionManager" entry-point-ref="authenticationEntryPoint">然后我們來寫CaptchaAuthenticationFilter,同樣需要繼承自UsernamePasswordAuthenticationFilter
public class CaptchaAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ public static final String SPRING_SECURITY_FORM_CAPTCHA_KEY = "j_captcha"; public static final String SESSION_GENERATED_CAPTCHA_KEY = Constant.SESSION_GENERATED_CAPTCHA_KEY; private String captchaParameter = SPRING_SECURITY_FORM_CAPTCHA_KEY; public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String genCode = this.obtainGeneratedCaptcha(request); String inputCode = this.obtainCaptcha(request); if(genCode == null) throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaInvalid")); if(!genCode.equalsIgnoreCase(inputCode)){ throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaNotEquals")); } return super.attemptAuthentication(request, response); } protected String obtainCaptcha(HttpServletRequest request){ return request.getParameter(this.captchaParameter); } protected String obtainGeneratedCaptcha (HttpServletRequest request){ return (String)request.getSession().getAttribute(SESSION_GENERATED_CAPTCHA_KEY); } }在配置文件中配置CaptchaAuthenticationFilter
<bean id="captchaAuthenticaionFilter" class="com.zrhis.system.security.CaptchaAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationFailureHandler" ref="authenticationFailureHandler" /> <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" /> <property name="filterProcessesUrl" value="/login.do" /> </bean> <bean id="authenticationSuccessHandler" class="com.zrhis.system.security.SimpleLoginSuccessHandler"> <property name="defaultTargetUrl" value="/WEB-INF/app.jsp"></property> <property name="forwardToDestination" value="true"></property> </bean> <bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login.jsp" /> </bean>從配置文件中就可以看出來authenticationManager、authenticationFailureHandler、authenticationSuccessHandler、filterProcessesUrl等都需要我們自行注入了。
filterProcessesUrl定義的是登錄驗證的地址,默認的是j_spring_security_check這里我們改成login.do
authenticationSuccessHandler中的defaultTargetUrl定義的是登錄成功后跳轉到的頁面
authenticationFailureHandler中的defaultTargetUrl定義的是登錄失敗后跳轉到的頁面
我們的首頁app.jsp在/WEB-INF下所以需要使用服務器跳轉,所以需要將forwardToDestination設為true,因為客戶端跳轉是不能直接訪問WEB-INF下的內容的。
最后在http中將FORM_LOGIN_FILTER替換掉,最終http中完整的配置就變成了下面的內容
<sec:http access-decision-manager-ref="accessDecisionManager" entry-point-ref="authenticationEntryPoint"> <sec:access-denied-handler ref="accessDeniedHandler"/> <sec:session-management invalid-session-url="/login.jsp" /> <sec:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/> <sec:custom-filter ref="captchaAuthenticaionFilter" position="FORM_LOGIN_FILTER"/> </sec:http>custom-filter中before是在這個filter之前,after是之后,position是替換。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Spring Security-- 验证码功能的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英语中sit和seat区别
- 下一篇: Spring boot 系列 入门--配