Spring Security 验证码

news/2024/11/13 4:30:58/

原理、存在问题、解决思路
我们知道Spring Security是通过过滤器链来完成了,所以它的解决方案是创建一个过滤器放到Security的过滤器链中,在自定义的过滤器中比较验证码

1 添加依赖(生成验证码)

<!--引入hutool-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.9</version>
</dependency>

2 生产验证码

CodeController


@Controller
@RequestMapping("/code")
public class CodeController {@RequestMapping("/img")public void code(HttpServletRequest request, HttpServletResponse response) {//创建验证码长,宽,字符数,干扰元素个数CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);// 放在session里面System.out.println("生成的验证码" + circleCaptcha.getCode());request.getSession().setAttribute("circleCaptcha", circleCaptcha.getCode());// 用流写出去try {ImageIO.write(circleCaptcha.getImage(), "JPEG", response.getOutputStream());} catch (IOException e) {e.printStackTrace();}}
}

3 创建验证码过滤器

ValidateCodeFilter

@Component
public class ValidateCodeFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {//得到请求地址String requestURI = request.getRequestURI();System.out.println("requestURL" + requestURI);//判断是否是登录请求if (requestURI.equals("/login/doLogin")) {//说明当前请求为登陆//1,得到登陆时用户输入的验证码String code1 = request.getSession().getAttribute("circleCaptcha").toString();String code = request.getParameter("code");System.out.println("用户输入的验证码:" + code);if (StringUtils.hasText(code)) {if (code.equalsIgnoreCase(code1)) {//说明验证码正确  直接放行request.getSession().removeAttribute("errorMSg");filterChain.doFilter(request, response);return;} else {//说明验证码不正确,返回登陆页面request.getSession().setAttribute("errorMsg", "验证码错误");response.sendRedirect("/index/toLogin");return;}} else {//用户没有输出验证码重定向到登陆页面request.getSession().setAttribute("errorMsg", "验证码不能为空");response.sendRedirect("/index/toLogin");return;}} else {//说明不是登陆 直接放行到下一个过滤器filterChain.doFilter(request, response);return;}}
}

4 配置类放行

在这里插入图片描述
在这里插入图片描述


@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {/*注入 登录成功处理器*/@Autowiredprivate AppAuthenticationSuccessHandler appAuthenticationSuccessHandler;/*注入 登录 失败处理器*/@Autowiredprivate AppAuthenticationFailureHandler appAuthenticationFailureHandler;/*注入  没有权限处理器*/@Autowiredprivate AppAccessDeniedHandler appAccessDeniedHandler;/*注入 登出成功处理器*/@Autowiredprivate AppLogoutSuccessHandler appLogoutSuccessHandler;@Autowiredprivate AppUserDetailsService appUserDetailsService;//验证码拦截器注入@Autowiredprivate ValidateCodeFilter validateCodeFilter;/*配置多用户*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(appUserDetailsService);}/*http请求配置*/@Overrideprotected void configure(HttpSecurity http) throws Exception {
//        super.configure(http);// 不使用父类的 方法, 需要 提供登录配置/*没权权限的处理*/
//        http.exceptionHandling().accessDeniedHandler(appAccessDeniedHandler);/*登录*/// 配置登录之前添加一个验证码的过滤器http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);http.formLogin().usernameParameter("uname")//页面表单账号的参数名  默认 为 username.passwordParameter("pwd")//页面表单密码的参数名   默认 为 password.loginPage("/index/toLogin")//定义登录页面的 请求 地址(转发到登录页面).loginProcessingUrl("/login/doLogin")// 表单提交的 地址(不需要提供),登录验证......successForwardUrl("/index/toIndex")//登录成功 跳转的路径.failureForwardUrl("/index/toLogin")//登录失败 跳转的路径
//                .successHandler(appAuthenticationSuccessHandler)//登录成功处理器
//                .failureHandler(appAuthenticationFailureHandler)//登录失败处理器.permitAll();;/*登出*/http.logout().logoutUrl("/logout")//登出的 请求地址.logoutSuccessUrl("/index/toLogin")//登出成功后 访问的路径
//                .logoutSuccessHandler(appLogoutSuccessHandler)//登出成功处理器.permitAll();/*设置 资源所需要的 权限 (好比 门上锁)*/http.authorizeRequests()
//                .mvcMatchers("/index/toLogin", "/index.html","/code/img").permitAll()//不需要认证就可以访问.antMatchers("/code/img")  // 放行验证码的路径.permitAll().anyRequest().authenticated()//所有请求都需要登录认证 才能进行;/*禁用csrf跨域请求攻击   如果不禁用  自定义的登录页面无法登录*/http.csrf().disable();}/*资源服务匹配放行:静态资源*/@Overridepublic void configure(WebSecurity web) throws Exception {
//        super.configure(web);web.ignoring().antMatchers("/css/**");}/*强制要求配置 密码加密器*/@Bean// 将对象 交给 spring容器 管理public PasswordEncoder passwordEncoder() {
//        return NoOpPasswordEncoder.getInstance();//不加密return new BCryptPasswordEncoder();}}

5 前端template

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户登陆</title>
</head>
<body>
<h2>登录页面</h2>
<!--${param.error}这个如果有值,就显示帐号或密码错误-->
<h4 th:if="${session.errorMsgs}" style="color: #c41f1f;">帐号或密码错误,请重新输入</h4>
<form action="/login/doLogin" method="post"><table><tr><td>用户名:</td><td><input type="text" name="uname" value="zhangsan"></td></tr><tr><td>密码:</td><td><input type="password" name="pwd" value="123456"></td></tr><td>验证码:</td><td><input type="text" name="code"> <img src="/code/img" style="height:33px;cursor:pointer;"onclick="this.src=this.src"><span th:text="${session.errorMsg}" style="color: #FF0000;"></span></td><tr><td colspan="2"><button type="submit">登录</button></td></tr></table>
</form>
</body>

效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/833862.html

相关文章

c语言sn求和问题

第一种&#xff1a;求Snaaaaaa…aa…aaa&#xff08;有n个a&#xff09;之值&#xff0c;其中a是一个数字&#xff0c;为2。 例如&#xff0c;n5时222222222222222&#xff0c;n由键盘输入。 此想法是先用循环计算出第n个数有几个a&#xff0c;再把前面的所有数相加 第二种&…

unpkg 与 npm 的基本介绍

目录 定义 特点 原理 使用 npm安装流程 npm install npm update registry 区别 总结 定义 UNPKG是一个基于npm registry 的静态资源 CDN 服务&#xff0c;它可以快速获取和使用任何JavaScript包&#xff0c;无需安装任何软件或包。UNPKG可以从NPM仓库中获取任何包&am…

RabbitMQ集群搭建与高可用实现(未完待续)

文章目录 一、RabbitMQ集群概述1、为什么要使用RabbitMQ集群2、RabbitMQ如何支持集群3、RabbitMQ的节点类型 二、普通集群1、什么是普通集群2、Docker搭建普通集群模式&#xff08;1&#xff09;安装docker&#xff08;2&#xff09;安装RabbitMQ&#xff08;3&#xff09;检验…

Acrobat Pro DC 18.011.20040 完整破解版

此版特点 by vposy # 集成AMTLIB模拟授权(v0.9.2)&#xff0c;免序列号&#xff0c;破解激活永久授权完整版&#xff01; # 集成最新AAMv10(CS10)/ACCC SP&#xff0c;集成软件所需的VC运行库&#xff1b; # 移除自动更新&#xff0c;移除试用提示&#xff0c;移除菜单更新&am…

最好用的pdf阅读软件 Acrobat Reader DC安装教程(无需破解)

下载在线安装的小文件 直通车 若无法打开&#xff08;FQ&#xff09;可以下载我已经下载好了的 https://pan.baidu.com/s/1jzd8CnB4sHLCCwQvztLmYg 就这个小文件&#xff0c;双击便会在线下载安装。默认安装在C盘 由于我已经安装了&#xff0c;所以只是检测我的是否为最新…

Soft-ICE使用说明及实例——破解ACDSee

http://blog.csdn.net/he_rong/archive/2004/06/25/25906.aspx 为了以后说话方便, 这里把 Soft-ICE 的一些简单使用方法说一下, 以免不通 E 文的同志们找不到中文的 Soft-ICE 说明而抓瞎.   Soft-ICE 由三部分 (以后说的 Soft-ICE, 如果不加特殊说明, 均指 Soft-ICE for Wind…

ACDSee Pro 6.0.169 (x86) crack by XenoCoder

http://www.datafilehost.com/download-f12967bb.html

Cadence License破解失败解决办法

问题1&#xff1a;Unable to restart Cadence License Server with the new license file 这个问题是在运行License Server Configuration Utility时可能遇到的。 Cadence破解license&#xff0c;指定license文件时&#xff0c;提升下列的报错&#xff1a; Unable to restart…