Spring-Security 自定義Filter完成驗證碼校驗

 Spring-Security的功能主要是由一堆Filter構成過濾器鏈來實現,每個Filter都會完成自己的一部分工作。我今天要做的是對UsernamePasswordAuthenticationFilter進行擴展,新增一個Filter,完成對登錄頁面的校驗碼的驗證。下面先給一張過濾器的說明,接下來講自定義的登錄驗證Filter。

? ??https://docs.spring.io/spring-security/site/docs/3.2.8.RELEASE/reference/htmlsingle/#ns-web-advanced

? ?

? ?一、擴展AbstractAuthenticationProcessingFilter,實現MyUsernamePasswordAuthenticationFilter。

package simm.spring.web.config;import java.io.IOException;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StringUtils;public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter  {// 是否開啟驗證碼功能private boolean isOpenValidateCode = true;public static final String VALIDATE_CODE = "validateCode";public MyUsernamePasswordAuthenticationFilter() {super(new AntPathRequestMatcher("/user/login.do", "POST"));SimpleUrlAuthenticationFailureHandler failedHandler = (SimpleUrlAuthenticationFailureHandler)getFailureHandler();failedHandler.setDefaultFailureUrl("/user/login.do?validerror");}@Override  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  HttpServletRequest req = (HttpServletRequest) request;  HttpServletResponse res=(HttpServletResponse)response;if (!requiresAuthentication(req, res)) {chain.doFilter(request, response);return;}if (isOpenValidateCode) {if(!checkValidateCode(req, res))return;}//保存一些session信息HttpSession session = req.getSession();session.setAttribute(VALIDATE_CODE, "mytest");chain.doFilter(request,response);  }  /*** 覆蓋授權驗證方法,這里可以做一些自己需要的session設置操作*/public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {return null;}protected boolean checkValidateCode(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {HttpSession session = request.getSession();String sessionValidateCode = obtainSessionValidateCode(session);sessionValidateCode = "1234";// 做個假的驗證碼;// 讓上一次的驗證碼失效session.setAttribute(VALIDATE_CODE, null);String validateCodeParameter = obtainValidateCodeParameter(request);if (StringUtils.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {unsuccessfulAuthentication(request, response, new InsufficientAuthenticationException("輸入的驗證碼不正確"));  return false;}return true;}private String obtainValidateCodeParameter(HttpServletRequest request) {Object obj = request.getParameter(VALIDATE_CODE);return null == obj ? "" : obj.toString();}protected String obtainSessionValidateCode(HttpSession session) {Object obj = session.getAttribute(VALIDATE_CODE);return null == obj ? "" : obj.toString();}
}

  代碼解讀

  1、為Filter指定請求地址過濾器,用于攔截登錄請求。調用AbstractAuthenticationProcessingFilter.requiresAuthentication方法。

? ? ? ? ? ? ?

  2、指定驗證失敗的跳轉頁面

  

  3、驗證碼的測試代碼。假的驗證碼1234,與頁面參數比對后,如果不相等則拋出"輸入的驗證碼不正確"的異常。

  

  4、驗證通過,繼續執行后續的Filter鏈。否則退出請求處理邏輯。這個Filter只處理驗證碼的校驗邏輯,用戶名密碼的驗證交給后面的UsernamePasswordAuthenticationFilter來處理。

  

? ?二、向HttpSecurity的Filter鏈上插入自定義的Filter,插入到UsernamePasswordAuthenticationFilter的位置上。插入方法有addFilterBefore,addFilterAt,addFilterAfter。這個地方需要注意使用addFilterAt并不是說能替換掉原有的Filter,事實上框架原有的Filter在啟動HttpSecurity配置的過程中,都由框架完成了其一定程度上固定的配置,是不允許更改替換的。根據測試結果來看,調用addFilterAt方法插入的Filter,會在這個位置上的原有Filter之前執行。

@Overrideprotected void configure(HttpSecurity http) throws Exception {String doUrl = "/**/*.do";http.addFilterAt(new MyUsernamePasswordAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class)

  三、登錄方法添加對驗證碼錯誤回調的攔截

@Controller
@RequestMapping("/user")
public class UserController {@RequestMapping(value = "/login", method = RequestMethod.GET)public String login(@RequestParam(value = "error", required = false) String error,@RequestParam(value = "validerror", required = false) String validerror,@RequestParam(value = "logout", required = false) String logout,Model model) {if (error != null) {model.addAttribute("msg", "用戶名或密碼錯誤!");}if(validerror!=null){model.addAttribute("msg", "驗證碼錯誤!");}if (logout != null) {model.addAttribute("msg", "成功退出!");}return "user/login";}

? ? ?四、測試結果展示

  

  以上就是我對登錄功能的自定義Filter實現。其他Filter都是同理,如果需要都可以自行擴展。東西不多,希望對你有所幫助,歡迎留言交流。

轉載于:https://www.cnblogs.com/MrSi/p/8032936.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/390556.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390556.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390556.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何使用Ionic和Firebase在短短三天內創建冠狀病毒跟蹤器應用程序

I am really fond of Hybrid App technologies – they help us achieve so much in a single codebase. Using the Ionic Framework, I developed a cross-platform mobile solution for tracking Coronavirus cases in just 3 days. 我真的很喜歡Hybrid App技術-它們可以幫助…

二、Java面向對象(7)_封裝思想——this關鍵字

2018-04-30 this關鍵字 什么是this: 表示當前對象本身,或當前類的一個實例,通過 this 可以調用本對象的所有方法和屬性。 this主要存在于兩個地方: 1)構造函數:此時this表示調用當前創建的對象 2)成員方法中…

機器學習模型 非線性模型_調試機器學習模型的終極指南

機器學習模型 非線性模型You’ve divided your data into a training, development and test set, with the correct percentage of samples in each block, and you’ve also made sure that all of these blocks (specially development and test set) come from the same di…

leetcode 645. 錯誤的集合

集合 s 包含從 1 到 n 的整數。不幸的是,因為數據錯誤,導致集合里面某一個數字復制了成了集合里面的另外一個數字的值,導致集合 丟失了一個數字 并且 有一個數字重復 。 給定一個數組 nums 代表了集合 S 發生錯誤后的結果。 請你找出重復出…

Linux環境變量總結

現在每天測試到時候會與Linux打交道,自然也會用到環境變量了。看了網上幾篇文章,結合自己到實踐和看法,總結以下Linux的環境變量吧。一、什么是環境變量?環境變量相當于給系統或用戶應用程序設置的一些參數, 具體起什么作用這當然…

目錄指南中的Python列表文件-listdir VS system(“ ls”)通過示例進行解釋

🔹歡迎 (🔹 Welcome) If you want to learn how these functions work behind the scenes and how you can use their full power, then this article is for you.如果您想了解這些功能在后臺如何工作以及如何充分利用它們的功能,那么本文適合…

Java多線程并發學習-進階大綱

1、synchronized 的實現原理以及鎖優化?2、volatile 的實現原理?3、Java 的信號燈?4、synchronized 在靜態方法和普通方法的區別?5、怎么實現所有線程在等待某個事件的發生才會去執行?6、CAS?CAS 有什么缺陷…

大數據定律與中心極限定理_為什么中心極限定理對數據科學家很重要?

大數據定律與中心極限定理數據科學 (Data Science) The Central Limit Theorem is at the center of statistical inference what each data scientist/data analyst does every day.中心極限定理是每個數據科學家/數據分析師每天所做的統計推斷的中心。 Central Limit Theore…

useEffect語法講解

useEffect語法講解 用法 useEffect(effectFn, deps)能力 useEffect Hook 相當于 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個函數的組合。 可以模擬渲染后、更新后、銷毀三個動作。 案例演示 渲染后更新標題 useEffect(()>{doc…

leetcode 726. 原子的數量

給定一個化學式formula(作為字符串),返回每種原子的數量。 原子總是以一個大寫字母開始,接著跟隨0個或任意個小寫字母,表示原子的名字。 如果數量大于 1,原子后會跟著數字表示原子的數量。如果數量等于 1…

web相關基礎知識1

2017-12-13 09:47:11 關于HTML 1.絕對路徑和相對路徑 相對路徑:相對于文件自身為參考。 (工作中一般是使用相對路徑) 這里我們用html文件為參考。如果說html和圖片平級,那直接使用src 如果說圖片在和html平級的文件夾里面&#xf…

JavaScript循環:標簽語句,繼續語句和中斷語句說明

標簽聲明 (Label Statement) The Label Statement is used with the break and continue statements and serves to identify the statement to which the break and continue statements apply. Label語句與break和continue語句一起使用,用于標識break和continue語…

馬約拉納費米子:推動量子計算的“天使粒子”

據《人民日報》報道,以華人科學家為主體的科研團隊找到了正反同體的“天使粒子”——馬約拉納費米子,從而結束了國際物理學界對這一神秘粒子長達80年的漫長追尋。該成果由加利福尼亞大學洛杉磯分校何慶林、王康隆課題組,美國斯坦福大學教授張…

leetcode 1711. 大餐計數

大餐 是指 恰好包含兩道不同餐品 的一餐,其美味程度之和等于 2 的冪。 你可以搭配 任意 兩道餐品做一頓大餐。 給你一個整數數組 deliciousness ,其中 deliciousness[i] 是第 i?????????????? 道餐品的美味程度,返回你可以用…

您的第一個簡單的機器學習項目

This article is for those dummies like me, who’ve never tried to know what machine learning was or have left it halfway for the sole reason of being overwhelmed. Follow through every line and stay along. I promise you’d be quite acquainted with giving yo…

eclipse報Access restriction: The type 'BASE64Decoder' is not API處理方法

今天從svn更新代碼之后,由于代碼中使用了BASE64Encoder 更新之后報如下錯誤: Access restriction: The type ‘BASE64Decoder’ is not API (restriction on required library ‘D:\java\jdk1.7.0_45\jre\lib\rt.jar’) 解決其實很簡單,把JR…

【躍遷之路】【451天】程序員高效學習方法論探索系列(實驗階段208-2018.05.02)...

(躍遷之路)專欄 實驗說明 從2017.10.6起,開啟這個系列,目標只有一個:探索新的學習方法,實現躍遷式成長實驗期2年(2017.10.06 - 2019.10.06)我將以自己為實驗對象。我將開源我的學習方法,方法不斷…

react jest測試_如何使用React測試庫和Jest開始測試React應用

react jest測試Testing is often seen as a tedious process. Its extra code you have to write, and in some cases, to be honest, its not needed. But every developer should know at least the basics of testing. It increases confidence in the products they build,…

面試題 17.10. 主要元素

題目 數組中占比超過一半的元素稱之為主要元素。給你一個 整數 數組,找出其中的主要元素。若沒有,返回 -1 。請設計時間復雜度為 O(N) 、空間復雜度為 O(1) 的解決方案。 示例 1: 輸入:[1,2,5,9,5,9,5,5,5] 輸出:5 …

簡單團隊-爬取豆瓣電影T250-項目進度

本次主要講解一下我們的頁面設計及展示最終效果: 頁面設計主要用到的軟件是:html,css,js, 主要用的編譯器是:sublime,dreamweaver,eclipse,由于每個人使用習慣不一樣&…