4.Spring Security 图片验证码技术

Security+jwt+验证码实现验证和授权 微服务Security+jwt+验证码实现认证和授权简要介绍基本流程核心代码测试 简要介绍 本次博客采用Spring Security、jwt、验证码的形式实现登录验证,项目本上是一个前后端分离项目。如果你的项目在登陆时不需要验证码,你只需要在后续的代码中,将有关验证码的过滤器删除。 基本流程 1、前端请求后端"/captcha"验证码接口,后端生成验证码文本及编码并将其存入redis缓存,然后返回验证码文本(五个字符)和验证码base64编码给前端。 2、前端显示验证码图片,用户输入用户名、密码、验证码 阅读详情

1.增加图片验证代码

// 图片验证码信息
public class ImageCode {

    // 图片
    private BufferedImage image;

    // 随机数
    private String code;

    // 过期时间
    private LocalDateTime expireTime;

    public ImageCode() {}

    public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {
        this.image = image;
        this.code = code;
        this.expireTime = expireTime;
    }

    // expireIn 过多久图形验证码 过期
    public ImageCode(BufferedImage image, String code, int expireIn) {
        this.image = image;
        this.code = code;
        this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
    }

    // 验证是否过期
    public boolean isExpire () {
        return LocalDateTime.now().isAfter(expireTime);
    }

    public BufferedImage getImage() {
        return image;
    }

    public void setImage(BufferedImage image) {
        this.image = image;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public LocalDateTime getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(LocalDateTime expireTime) {
        this.expireTime = expireTime;
    }

}

2.编写 imageController 用来给前端提供图片验证码,并且把图片信息写入session

// 生成校验码的请求处理器
@RestController
public class imageController {

    public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";

    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    @GetMapping("/code/image")
    public void createCode (HttpServletRequest request, HttpServletResponse response) throws IOException {
        ImageCode imageCode = createImage(request);
        sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);
        ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
    }

    private ImageCode createImage(HttpServletRequest request) {
        int width = 67;
        int height = 23;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics g = image.getGraphics();

        Random random = new Random();

        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Times New Roman", Font.ITALIC, 20));
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }

        String sRand = "";
        for (int i = 0; i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            g.drawString(rand, 13 * i + 6, 16);
        }

        g.dispose();

        // 有效期
        return new ImageCode(image, sRand, 60);
    }

    /**
     * 生成随机背景条纹
     *
     * @param fc
     * @param bc
     * @return
     */
    private Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }
}

3.前端代码增加验证码输入框

<form action="/login/form" method="post">
    <table>
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>图形验证码:</td>
            <td>
                <input type="text" name="imageCode">
                <img src="/code/image">
            </td>
        </tr>

        <tr>
            <td colspan="2"><button type="submit">登录</button></td>
        </tr>
    </table>
</form>

4.增加验证码过滤器

// OncePerRequestFilter : 保证过滤器只被调用一次
public class ValidateCodeFilter extends OncePerRequestFilter {

    private AuthenticationFailureHandler authenctiationFailureHandler;

    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    // 过滤 逻辑
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 是一个登陆请求
        if (StringUtils.equals("/login/form", request.getRequestURI())
                && StringUtils.equalsIgnoreCase(request.getMethod(), "POST")) {
            try {
                validate(new ServletWebRequest(request));
            } catch (ValidateCodeException e) {
                // 有异常就返回自定义失败处理器
                authenctiationFailureHandler.onAuthenticationFailure(request, response, e);
                return;
            }
        }
        // 不是一个登录请求,不做校验 直接通过
        filterChain.doFilter(request, response);
    }

    private void validate(ServletWebRequest request) throws ServletRequestBindingException {
        ImageCode codeInSession = (ImageCode) sessionStrategy.getAttribute(request, imageController.SESSION_KEY);

        String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "imageCode");

        if (StringUtils.isBlank(codeInRequest)) {
            throw new ValidateCodeException("验证码不能为空!");
        }

        if (codeInSession == null) {
            throw new ValidateCodeException("验证码不存在");
        }

        if (codeInSession.isExpire()) {
            sessionStrategy.removeAttribute(request, imageController.SESSION_KEY);
            throw new ValidateCodeException("验证码已过期");
        }

        if (!StringUtils.equals(codeInSession.getCode(), codeInRequest)) {
            throw new ValidateCodeException("验证码不匹配");
        }

        sessionStrategy.removeAttribute(request, imageController.SESSION_KEY);

    }

    public AuthenticationFailureHandler getAuthenctiationFailureHandler() {
        return authenctiationFailureHandler;
    }

    public void setAuthenctiationFailureHandler(AuthenticationFailureHandler authenctiationFailureHandler) {
        this.authenctiationFailureHandler = authenctiationFailureHandler;
    }

}

AuthenticationException 自定义一个异常处理

/**
 * @author zhailiang
 *
 */
public class ValidateCodeException extends AuthenticationException {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7285211528095468156L;

	public ValidateCodeException(String msg) {
		super(msg);
	}

}

5.修改Security 配置文件WebSecurityConfigurerAdapter增加前置过滤器
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)

@Configuration
public class MySecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthenticationSuccessHandler MyAuthenticationSuccessHandler;

    @Autowired
    AuthenticationFailureHandler MyAuthenticationFailureHandler;

    @Bean
    PasswordEncoder passwordEncoder()
    {
        // return NoOpPasswordEncoder.getInstance();
        return  new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
        validateCodeFilter.setAuthenctiationFailureHandler(MyAuthenticationFailureHandler);
        //把 图片验证码 过滤器加到 UsernamePasswordAuthenticationFilter 前面
        http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
                //formlogin登录
                .formLogin()
                //自定义的登录页面
                .loginPage("/login.html")
                //让form表单的用户名和密码走 系统认证
                .loginProcessingUrl("/login/form")
                .successHandler(MyAuthenticationSuccessHandler)
                .failureHandler(MyAuthenticationFailureHandler)
                .and()
                //任何请求都进行拦截
                .authorizeRequests()
                //不需要身份认证的项目。匹配器
                .antMatchers("/code/image","/login.html").permitAll()
                //所有的请求
                .anyRequest()
                //都要身份认证
                .authenticated()
                 .and()
                //跨站请求关掉
                .csrf().disable();
    }
}

7.前台演示
在这里插入图片描述

交换机基本介绍(分类、性能指标、硬件构成及工作方式) 一、交换机的分类与性能指标 1.1交换机的分类 按照网络构成方式来分的话,交换机分为三类:接入层交换机、汇聚层交换机和核心层交换机。 按照OSI模型来划分的话,分为:二层交换机、三层交换机和四层交换机 还有一种按照硬件形态来划分,可以分成两类:盒式交换机和机框式交换机。 盒式交换机是一种有固定端口数,有时也会带有少量扩展槽的交换机。机架式交换机是一种插槽式的交换机,这种交换机扩展性较好,可支持不同的网络类型,可支持更大端口密度的网络。一般在数据中心的接入层都会采用盒式交换机,盒式... 阅读详情

相关推荐

auboi5 + d435i 使用easy handeye进行标定时,遇到相关问题记录。

解决办法:在easy_handeye默认的 calibrate.launch 文件中move group 的默认值为 "manipulator",但针对每个人的机械臂,这个值需要更改。以aubo_i5为例,需要将其改为"manipulator_i5",或者自己编写launch文件时,传入参数move group的值,便能顺利解决问题!easy_handeye_calibration_server 进程出现崩溃。

weixin_61025092的博客 958

SpringSecurity(03)——图形验证码和短信验证码

SpringSecurity图形验证码和短信验证码

peng_gx的博客 1515

事件相机(Event Camera)及相关研究简介——新一代相机?新的计算机视觉领域?

事件相机(Event Camera)及相关研究简介 事件相机是一个新型的类脑相机,是一个待开发的大领域。希望通过我的分享,能够有更多人来研究并将它更好地运用在我们的生活中~

Cyril的博客 5万+

9-SpringSecurity:登录时的图片验证码,小白看完都会了

分布式技术专题+面试解析+相关的手写和学习的笔记pdf还有更多Java笔记分享如下:程,基本涵盖了95%以上Java开发知识点,真正体系化!**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)[外链图片转存中…(img-B54g3xjL-1712066022808)]分布式技术专题+面试解析+相关的手写和学习的笔记pdf。

2401_83977554的博客 1247

别再手动切换了!用SP3485+三极管搞定RS485自动收发电路(附完整原理图)

本文详细介绍了如何利用SP3485芯片和三极管设计RS485自动收发电路,解决传统手动切换带来的IO资源占用和软件复杂度问题。通过原理分析、电路设计拆解和实战注意事项,帮助工程师打造稳定可靠的自动收发通信模块,显著提升系统性能和可靠性。

weixin_26833939的博客 513

linux 驱动 - pinctrl子系统

分析总结 pinctrl 子系统框架结构,平台 mtk6771 内核版本 kernel-4.4 , 本文所有的分析均基于此版本。

sty01z的博客 1557

Spring Security 在登录时如何添加图形验证码

这里继承的过滤器为,并重写方法。用户登录的用户名/密码是在类中处理,那我们就继承这个类,增加对验证码的处理。、,不过处理起来会比继承麻烦一点。@Override// 需要是 POST 请求if (!}// 获得请求验证码值// 获得 session 中的 验证码值throw new AuthenticationServiceException("验证码不能为空!");}

BASK2312的博客 1319

QNX Neutrino 进程间通信编程之Message-passing/Pulse

Interprocess Communication(IPC,进程间通信)在QNX Neutrino从一个嵌入式实时系统向一个全面的POSIX系统转变起着至关重要的作用。IPC是将在内核中提供各种服务的进程内聚在一起的粘合剂。在QNX中,消息传递是IPC的主要形式,也提供了其他的形式,除非有特殊的说明,否则这些形式也都是基于本地消息传递而实现的。本篇幅主要讲解Message-passing和Pulse。

zhuwade的博客 3533

SpringSecurity图形验证码认证

图形验证码认证 1.添加过滤器认证 1.1 生成一张图形验证码 Kaptcha 是谷歌提供的一个生成图形验证码的 jar 包, 只要简单配置属性就可以生成。 参考 :https://github.com/penggle/kaptcha 添加Kaptcha依赖 <!--短信验证码--> <dependency> <groupId>com...

qq_29860591的博客 572

从零部署DeepSeek V4 Flash:NVIDIA DGX Spark实战指南

GPU加速计算已成为现代人工智能基础设施的核心,其原理是通过并行处理架构大幅提升深度学习模型的训练与推理效率。在AI工程实践中,NVIDIA GPU凭借CUDA生态和专用驱动栈,为大规模语言模型部署提供了硬件基础。本文聚焦于企业级AI服务器部署场景,针对NVIDIA DGX Spark多节点系统的硬件初始化、驱动兼容性配置、容器化部署等关键环节,提供从系统层到应用层的完整解决方案。通过vLLM推理框架的实战配置,演示如何将DeepSeek V4 Flash模型高效部署于多GPU环境,涵盖Tensor Par

weixin_32296621的博客 379

基于Simulink和Control System Toolbox的线控转向(Steer-by-Wire)系统设计

通过上述步骤,我们成功设计并实现了基于 Simulink 和 Control System Toolbox 的线控转向(Steer-by-Wire)系统。该系统能够接收来自方向盘的角度指令,经过控制器处理后,驱动转向执行器(如电动机),实现对车辆前轮转向角度的精确控制。通过虚拟场景仿真、硬件在环测试和实车测试,验证了系统的响应速度、控制精度、车辆稳定性和实时性能,并通过参数优化进一步提升了系统的性能。

MHD0815的博客 550

基于SpringSecurity实现图片验证码登录功能

图片验证码登录验证1.验证码流程详解2.验证码生成3.验证码校验 1.验证码流程详解 验证码流程图解析: 客户端打开登陆页的时候就要发送一个生成图片验证码的请求 服务端接受请求,就要随机生成验证码图片,将图片验证码响应给前端页面,并且要将生成的验证码保存到session中,以便登录验证校验 客户端收到验证码图片后,填入表单信息后,发送登录请求 服务端在接受到前端传来的验证码参数,要先与session中的比对,如果相同,则响应正确,如果不匹配,则返回相应错误信息,如验证码不匹配 本次系统测试效果: 本次

xhnb的博客 1152

Java代码变更影响分析:从静态解析到动态调用图的实战全链路

本文介绍了Java代码提交影响分析的核心原理与实现方法。主要内容包括:1)静态分析技术,通过JavaParser解析AST构建调用图,记录类与方法间的调用关系;2)动态分析技术,使用ByteBuddy进行字节码增强,捕获运行时调用路径;3)JCCI工具实现,结合javalang、unidiff等技术分析代码改动影响,并将结果存储到SQLite数据库。文章提供了完整的代码示例,展示了从AST解析、动态调用跟踪到实际工具应用的完整技术栈,为代码变更影响分析提供了实用解决方案。

墨夶的博客 1252

4.Spring Security 添加图形验证码

Spring Security 短信验证码登录 在 Spring Security 添加图形验证码一节中,我们已经实现了基于 Spring Boot + Spring Security 的账号密码登录,并集成了图形验证码功能。时下另一种非常常见的网站登录方式为手机短信验证码登录,但 Spring Security 默认只提供了账号密码的登录认证逻辑,所以要实现手机短信验证码登录认证功能,我们需要模...

LoveSummer 2092

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【Spring Security OAuth2】- spring security - 图片验证码

作者简介:大家好,我是哥,前中兴通讯、美团架构师,现某互联网公司联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!

smart_an的专栏 966

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【Spring Security OAuth2】- spring security - 图片验证码重构

作者简介:大家好,我是哥,前中兴通讯、美团架构师,现某互联网公司联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!

smart_an的专栏 969

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

[Java实战]Spring Security 添加验证码(二十三)

本文介绍了如何在 Spring Security 中添加验证码功能,以增强 Web 应用的安全性。首先,文章概述了验证码的作用,包括防止暴力破解、自动注册和垃圾评论。接着,详细说明了环境准备,包括所需的 Java 版本、Spring Boot 版本和构建工具。然后,文章逐步讲解了如何在 Spring Boot 项目中添加验证码功能,包括添加依赖、配置验证码生成器、创建验证码控制器、修改登录页面以及在 SecurityConfig 中添加验证码校验逻辑。通过这些步骤,开发者可以轻松地在 Spring Secu

曼岛_的博客 1570

spring security 图片验证码

springsecurity图片验证码

weixin_43931625的博客 333

SpringSecurity——如何实现验证码登录页面

验证码生成与前端显示前端页面通过请求验证码图片。生成验证码(这里使用带扭曲干扰的验证码),并将验证码字符串存入 Session,再将验证码图片通过 IO 流输出给前端。请求访问控制Spring Security 配置中允许/toLogin(登录页面)和(验证码图片接口)未登录访问。其他请求都需要经过认证后才能访问。登录请求及验证码校验当用户提交登录表单(提交至/login)时,自定义的会首先介入:从请求中获取用户输入的验证码,并从 Session 中获取正确验证码。

gege_0606的博客 2391

Spring Security 添加验证码

直接上代码 生成验证码工具类 这个工具类很常见,网上也有很多,就是画一个简单的验证码,通过流将验证码写到前端页面 public class VerificationCode { private int width = 100;// 生成验证码图片的宽度 private int height = 30;// 生成验证码图片的高度 private String[] fontNa...

暴走猿人的博客 430

spring security 实现登录验证码及记住我

spring security 验证码登录:   在现在主流的网站登录页上,我们经常可以看到登陆的时候是通过账号密码登录,那么时常会看到需要我们输入一个图片验证码里面的值。或者通过手机验证码进行短信登陆,进行获取验证码进行登录。而这两种登陆方式都用到了验证码,前者是图片验证码,后者是短信验证码。在spring security 中使用验证码来验证登录,其核心还是拦截器链,当请求获取验证码...

吴振照 1002

spring security 登录验证码

验证码网上有,可以参考下 先实现获取验证码 @GetMapping(value = "/verify-code") public String verityCode(HttpServletResponse response, HttpSession session) { Captcha captcha = new Captcha(); Buff...

征途人生&梦 917

Spring Security(三):认证(Authentication)-图片验证码登录

Spring Security实现的基本原理就是一堆过滤器,每个需要认证的请求都需要经过每个拦截器的拦截,如果所有拦截器都不报错就表示该用户有权限访问访问该接口,如果没有权限就抛异常。Spring Security登录时会经过UsernamePasswordAuthenticationFilter过滤器来校验用户名和密码,Spring Security并没有提供用于校验验证码的过滤器,所以实现验...

人不风流枉少年 1787

Spring全家桶-Spring Security之图片验证码

Spring全家桶-Spring Security之图片验证码 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(控制反转),DI(依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。 文章目录Spring全家桶-Spring Security之图片验证码为什么需要验证码?一

HQ DevJ的专栏 581

Spring Security图形验证码集成:基于AuthenticationProvider的原生认证流程扩展

在Web应用安全领域,身份认证是保护用户账户的第一道防线。Spring Security作为Java生态中主流的安全框架,其核心认证流程通过AuthenticationManager、AuthenticationProvider和UserDetailsService等组件协同工作,实现对用户名密码等凭证的校验。为了防御自动化脚本攻击,图形验证码成为登录环节的常见补充。传统的验证码校验往往在Controller或Filter中实现,这会导致安全逻辑碎片化,难以与Spring Security的异常处理、日志记

weixin_33913332的博客 435

Spring Security添加图形验证码

添加验证码大致可以分为三个步骤:根据随机数生成验证码图片;将验证码图片显示到登录页面;认证流程中加入验证码校验。Spring Security的认证校验是由UsernamePasswordAuthenticationFilter过滤器完成的,所以我们的验证码校验逻辑应该在这个过滤器之前。下面一起学习下如何在上一节Spring Security自定义用户认证的基础上加入验证码校验功能。 生成图形验...

Yestar123456的博客 362
上一篇: SpringSecurity基本原理
下一篇: 大数据应用-Spark集群的部署
精诚所至金石为开
博客等级 码龄8年 12粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值