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.mzph.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…

web相关基础知识1

2017-12-13 09:47:11 关于HTML 1.绝对路径和相对路径 相对路径:相对于文件自身为参考。 (工作中一般是使用相对路径) 这里我们用html文件为参考。如果说html和图片平级,那直接使用src 如果说图片在和html平级的文件夹里面&#xf…

您的第一个简单的机器学习项目

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…

简单团队-爬取豆瓣电影T250-项目进度

本次主要讲解一下我们的页面设计及展示最终效果: 页面设计主要用到的软件是:html,css,js, 主要用的编译器是:sublime,dreamweaver,eclipse,由于每个人使用习惯不一样&…

鸽子为什么喜欢盘旋_如何为鸽子回避系统设置数据收集

鸽子为什么喜欢盘旋鸽子回避系统 (Pigeon Avoidance System) Disclaimer: You are reading Part 2 that describes the technical setup. Part 1 gave an overview of the Pigeon Avoidance System and Part 3 provides details about the Pigeon Recognition Model.免责声明&a…

前端开发-DOM

文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。我们最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来。…

JAVA-初步认识-第十三章-多线程(验证同步函数的锁)

一. 至于同步函数用的是哪个锁,我们可以验证一下,借助原先卖票的例子 对于程序中的num,从100改为400,DOS的结果显示的始终都是0线程,票号最小都是1。 票号是没有问题的,因为同步了。 有人针对只出现0线程&a…

追求卓越追求完美规范学习_追求新的黄金比例

追求卓越追求完美规范学习The golden ratio is originally a mathematical term. But art, architecture, and design are inconceivable without this math. Everyone aspires to golden proportions as beautiful and unattainable perfection. By visualizing data, we chal…

leetcode 275. H 指数 II

给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照 升序排列 。编写一个方法,计算出研究者的 h 指数。 h 指数的定义: “h 代表“高引用次数”(high citations),一名科研…

leetcode 218. 天际线问题

城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示,其中三元组 buildings[i] [lefti, righti, heighti] 表示&#xff1a…

[Android Pro] 终极组件化框架项目方案详解

cp from : https://blog.csdn.net/pochenpiji159/article/details/78660844 前言 本文所讲的组件化案例是基于自己开源的组件化框架项目github上地址github.com/HelloChenJi…其中即时通讯(Chat)模块是单独的项目github上地址github.com/HelloChenJi… 1.什么是组件化&#xff…

leetcode 1818. 绝对差值和

给你两个正整数数组 nums1 和 nums2 &#xff0c;数组的长度都是 n 。 数组 nums1 和 nums2 的 绝对差值和 定义为所有 |nums1[i] - nums2[i]|&#xff08;0 < i < n&#xff09;的 总和&#xff08;下标从 0 开始&#xff09;。 你可以选用 nums1 中的 任意一个 元素来…

【转载】keil5中加入STM32F10X_HD,USE_STDPERIPH_DRIVER的原因

初学STM32&#xff0c;在RealView MDK 环境中使用STM32固件库建立工程时&#xff0c;初学者可能会遇到编译不通过的问题。出现如下警告或错误提示&#xff1a; warning: #223-D: function "assert_param" declared implicitly;assert_param(IS_GPIO_ALL_PERIPH(GPIOx…

剑指 Offer 53 - I. 在排序数组中查找数字 I(二分法)

统计一个数字在排序数组中出现的次数。 示例 1: 输入: nums [5,7,7,8,8,10], target 8 输出: 2 示例 2: 输入: nums [5,7,7,8,8,10], target 6 输出: 0 限制&#xff1a; 0 < 数组长度 < 50000 解题思路 先用二分法查找出其中一个目标元素再向目标元素两边查找…

MVC与三层架构区别

我们平时总是将三层架构与MVC混为一谈&#xff0c;殊不知它俩并不是一个概念。下面我来为大家揭晓我所知道的一些真相。 首先&#xff0c;它俩根本不是一个概念。 三层架构是一个分层式的软件体系架构设计&#xff0c;它可适用于任何一个项目。 MVC是一个设计模式&#xff0c;它…

tensorflow 实现逻辑回归——原以为TensorFlow不擅长做线性回归或者逻辑回归,原来是这么简单哇!...

实现的是预测 低 出生 体重 的 概率。尼克麦克卢尔&#xff08;Nick McClure&#xff09;. TensorFlow机器学习实战指南 (智能系统与技术丛书) (Kindle 位置 1060-1061). Kindle 版本. # Logistic Regression #---------------------------------- # # This function shows ho…

剑指 Offer 66. 构建乘积数组

给定一个数组 A[0,1,…,n-1]&#xff0c;请构建一个数组 B[0,1,…,n-1]&#xff0c;其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]A[0]A[1]…A[i-1]A[i1]…A[n-1]。不能使用除法。 示例: 输入: [1,2,3,4,5] 输出: [120,60,40,30,24] 提示&#xff1a; 所有…