返回顶部
首页 > 资讯 > 精选 >Springboot+SpringSecurity怎么实现图片验证码登录
  • 116
分享到

Springboot+SpringSecurity怎么实现图片验证码登录

2023-06-30 03:06:21 116人浏览 安东尼
摘要

本文小编为大家详细介绍“SpringBoot+springSecurity怎么实现图片验证码登录”,内容详细,步骤清晰,细节处理妥当,希望这篇“Springboot+SpringSecurity怎么实现图片验证码登录”文章能帮助大家解决疑惑

本文小编为大家详细介绍“SpringBoot+springSecurity怎么实现图片验证码登录”,内容详细,步骤清晰,细节处理妥当,希望这篇“Springboot+SpringSecurity怎么实现图片验证码登录”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

效果图

Springboot+SpringSecurity怎么实现图片验证码登录

网上大都是直接注入一个AuthenticationFailureHandler,我当时就不明白这个咋注进去的,我这个一写就报错,注入不进去,后来就想自己new一个哇,可以是可以了,但是还报异常,java.lang.IllegalStateException: Cannot call sendError() after the response has been committed,后来想表单验证的时候,失败用的也是这个处理器,就想定义一个全局的处理器,

package com.liruilong.hros.config; import com.fasterxml.jackson.databind.ObjectMapper;import com.liruilong.hros.Exception.ValidateCodeException;import com.liruilong.hros.model.RespBean;import org.springframework.context.annotation.Bean;import org.springframework.security.authentication.*;import org.springframework.security.core.AuthenticationException;import org.springframework.security.WEB.authentication.AuthenticationFailureHandler;import org.springframework.stereotype.Component; import javax.servlet.ServletException;import javax.servlet.Http.httpservletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter; @Componentpublic class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {    @Override    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {        httpServletResponse.setContentType("application/JSON;charset=utf-8");        PrintWriter out = httpServletResponse.getWriter();        RespBean respBean = RespBean.error(e.getMessage());           // 验证码自定义异常的处理        if (e instanceof ValidateCodeException){            respBean.setMsg(e.getMessage());            //Security内置的异常处理        }else if (e instanceof LockedException) {            respBean.setMsg("账户被定请联系管理员!");        } else if (e instanceof CredentialsExpiredException) {            respBean.setMsg("密码过期请联系管理员!");        } else if (e instanceof AccountExpiredException) {            respBean.setMsg("账户过期请联系管理员!");        } else if (e instanceof DisabledException) {            respBean.setMsg("账户被禁用请联系管理员!");        } else if (e instanceof BadCredentialsException) {            respBean.setMsg("用户名密码输入错误,请重新输入!");        }        //将hr转化为Sting        out.write(new ObjectMapper().writeValueAsString(respBean));        out.flush();        out.close();    }    @Bean    public  MyAuthenticationFailureHandler getMyAuthenticationFailureHandler(){        return new MyAuthenticationFailureHandler();    }}

流程 

  1.  请求登录页,将验证码结果存到基于Servlet的session里,以jsON格式返回验证码,

  2. 之后前端发送登录请求,SpringSecurity中处理,自定义一个filter让它继承自OncePerRequestFilter,然后重写doFilterInternal方法,在这个方法中实现验证码验证的功能,如果验证码错误就抛出一个继承自AuthenticationException的验证吗错误的异常消息写入到响应消息中.

  3. 之后返回异常信息交给自定义验证失败处理器处理。

下面以这个顺序书写代码:

依赖大家照着import导一下吧,记得有这两个,验证码需要一个依赖,之后还使用了一个工具依赖包,之后是前端代码

<!--图片验证-->        <dependency>            <groupId>com.GitHub.whvcse</groupId>            <artifactId>easy-captcha</artifactId>            <version>1.6.2</version>        </dependency>        <dependency>            <groupId>org.apache.commons</groupId>            <artifactId>commons-lang3</artifactId>        </dependency>
        <div class="login-code">          <img :src="codeUrl"               @click="getCode">        </div>

后端代码:

获取验证码,将结果放到session里

package com.liruilong.hros.controller; import com.liruilong.hros.model.RespBean;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import com.wf.captcha.ArithmeticCaptcha;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.HashMap;import java.util.Map; @RestControllerpublic class LoginController {        @GetMapping(value = "/auth/code")    public Map getCode(HttpServletRequest request,HttpServletResponse response){        // 算术类型 https://gitee.com/whvse/EasyCaptcha        ArithmeticCaptcha captcha = new ArithmeticCaptcha(111, 36);        // 几位数运算,默认是两位        captcha.setLen(2);        // 获取运算的结果        String result = captcha.text();        System.err.println("生成的验证码:"+result);        // 保存        // 验证码信息        Map<String,Object> imgResult = new HashMap<String,Object>(2){{            put("img", captcha.toBase64());            }};        request.getSession().setAttribute("yanzhengma",result);         return imgResult;    }}

定义一个VerifyCodeFilter 过滤器

package com.liruilong.hros.filter;  import com.liruilong.hros.Exception.ValidateCodeException;import com.liruilong.hros.config.MyAuthenticationFailureHandler;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.security.core.AuthenticationException;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;  @Componentpublic class VerifyCodeFilter extends OncePerRequestFilter {     @Bean    public VerifyCodeFilter getVerifyCodeFilter() {        return new VerifyCodeFilter();    }    @Autowired    MyAuthenticationFailureHandler myAuthenticationFailureHandler;    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {         if (StringUtils.equals("/doLogin", request.getRequestURI())                && StringUtils.equalsIgnoreCase(request.getMethod(), "post")) {            // 1. 进行验证码的校验            try {            String requestCaptcha = request.getParameter("code");                if (requestCaptcha == null) {                    throw new ValidateCodeException("验证码不存在");                }            String code = (String) request.getSession().getAttribute("yanzhengma");                if (StringUtils.isBlank(code)) {                    throw new ValidateCodeException("验证码过期!");                }            code = code.equals("0.0") ? "0" : code;            logger.info("开始校验验证码,生成的验证码为:" + code + " ,输入的验证码为:" + requestCaptcha);                if (!StringUtils.equals(code, requestCaptcha)) {                    throw new ValidateCodeException("验证码不匹配");                }            } catch (AuthenticationException e) {                // 2. 捕获步骤1中校验出现异常,交给失败处理类进行进行处理                myAuthenticationFailureHandler.onAuthenticationFailure(request, response, e);            } finally {                filterChain.doFilter(request, response);            }        } else {            filterChain.doFilter(request, response);        }      } }

定义一个自定义异常处理,继承AuthenticationException  

package com.liruilong.hros.Exception;  import org.springframework.security.core.AuthenticationException;   public class ValidateCodeException extends AuthenticationException  {     public ValidateCodeException(String msg) {        super(msg);    }  }

security配置. 

在之前的基础上加filter的基础上加了

http.addFilterBefore(verifyCodeFilter, UsernamePassWordAuthenticationFilter.class),验证处理上,验证码和表单验证失败用同一个失败处理器,

package com.liruilong.hros.config; import com.fasterxml.jackson.databind.ObjectMapper;import com.liruilong.hros.filter.VerifyCodeFilter;import com.liruilong.hros.model.Hr;import com.liruilong.hros.model.RespBean;import com.liruilong.hros.service.HrService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.*;import org.springframework.security.config.annotation.ObjectPostProcessor;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.AuthenticationEntryPoint;import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;import org.springframework.security.web.authentication.AuthenticationSuccesshandler;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.security.web.authentication.loGout.LogoutSuccessHandler; import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;  @Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {    @Autowired    HrService hrService;    @Autowired    CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;    @Autowired    CustomUrlDecisionManager customUrlDecisionManager;     @Autowired    VerifyCodeFilter verifyCodeFilter ;    @Autowired    MyAuthenticationFailureHandler myAuthenticationFailureHandler;     @Bean    PasswordEncoder passwordEncoder() {        return new BCryptPasswordEncoder();    }    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        auth.userDetailsService(hrService);    }        @Override    public void configure(WebSecurity web) throws Exception {        web.ignoring().antMatchers("/auth/code","/login","/CSS/**","/js/**", "/index.html", "/img/**", "/fonts/**","/favicon.ico");    }    @Override    protected void configure(HttpSecurity http) throws Exception {        http                .addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class)                .authorizeRequests()                //.anyRequest().authenticated()                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {                    @Override                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {                        object.setAccessDecisionManager(customUrlDecisionManager);                        object.setSecurityMetadataSource(customFilterInvocationSecurityMetadataSource);                        return object;                    }                })                .and().fORMLogin().usernameParameter("username").passwordParameter("password") .loginProcessingUrl("/doLogin")                .loginPage("/login")                //登录成功回调                .successHandler(new AuthenticationSuccessHandler() {                    @Override                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {                        httpServletResponse.setContentType("application/json;charset=utf-8");                        PrintWriter out = httpServletResponse.getWriter();                        Hr hr = (Hr) authentication.getPrincipal();                        //密码不回传                        hr.setPassword(null);                        RespBean ok = RespBean.ok("登录成功!", hr);                        //将hr转化为Sting                        String s = new ObjectMapper().writeValueAsString(ok);                        out.write(s);                        out.flush();                        out.close();                    }                })                //登失败回调                .failureHandler(myAuthenticationFailureHandler)                //相关的接口直接返回                .permitAll()                .and()                .logout()                //注销登录                // .logoutSuccessUrl("")                .logoutSuccessHandler(new LogoutSuccessHandler() {                    @Override                    public void onLogoutSuccess(HttpServletRequest httpServletRequest,                                                HttpServletResponse httpServletResponse,                                                Authentication authentication) throws IOException, ServletException {                        httpServletResponse.setContentType("application/json;charset=utf-8");                        PrintWriter out = httpServletResponse.getWriter();                        out.write(new ObjectMapper().writeValueAsString(RespBean.ok("注销成功!")));                        out.flush();                        out.close();                    }                })                .permitAll()                .and()                .csrf().disable().exceptionHandling()                //没有认证时,在这里处理结果,不要重定向                .authenticationEntryPoint(new AuthenticationEntryPoint() {                    @Override                    public void commence(HttpServletRequest req, HttpServletResponse resp, AuthenticationException authException) throws IOException, ServletException {                        resp.setContentType("application/json;charset=utf-8");                        resp.setStatus(401);                        PrintWriter out = resp.getWriter();                        RespBean respBean = RespBean.error("访问失败!");                        if (authException instanceof InsufficientAuthenticationException) {                            respBean.setMsg("请求失败,请联系管理员!");                        }                        out.write(new ObjectMapper().writeValueAsString(respBean));                        out.flush();                        out.close();                    }                });    }}

读到这里,这篇“Springboot+SpringSecurity怎么实现图片验证码登录”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

--结束END--

本文标题: Springboot+SpringSecurity怎么实现图片验证码登录

本文链接: https://lsjlt.com/news/327216.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Springboot+SpringSecurity怎么实现图片验证码登录
    本文小编为大家详细介绍“Springboot+SpringSecurity怎么实现图片验证码登录”,内容详细,步骤清晰,细节处理妥当,希望这篇“Springboot+SpringSecurity怎么实现图片验证码登录”文章能帮助大家解决疑惑...
    99+
    2023-06-30
  • Springboot+SpringSecurity实现图片验证码登录的示例
    这个问题,网上找了好多,结果代码都不全,找了好多,要不是就自动注入的类注入不了,编译报错,要不异常捕获不了浪费好多时间,就觉得,框架不熟就不能随便用,全是坑,气死我了,最后改了两天....
    99+
    2024-04-02
  • vue实现登录时的图片验证码
    本文实例为大家分享了vue实现登录时的图片验证码的具体代码,供大家参考,具体内容如下 效果图 一、新建vue组件components/identify/identify.vue ...
    99+
    2024-04-02
  • vue+springboot实现登录验证码
    本文实例为大家分享了vue+springboot实现登录验证码的具体代码,供大家参考,具体内容如下 先看效果图 在login页面添加验证码html 在后端pom文件添加kaptc...
    99+
    2024-04-02
  • SpringBoot+SpringSecurity+jwt实现验证
    目录环境目录结构信息记录一下使用springSecurity实现jwt的授权方法,这方法可以实现权限的基本认证。当然这个案例还有许多的问题,不过还是先记录一下。其他功能以后在补充。 ...
    99+
    2024-04-02
  • SpringSecurity实现添加图片验证功能
    目录本章内容思路方案怎么将字符串变成图片验证码kaptcha这么玩hutool这么玩传统web项目过滤器方式认证器方式总结下前后端分离项目基于过滤器方式基于认证器方式本章内容 Spr...
    99+
    2023-01-04
    Spring Security添加图片验证 Spring Security图片验证
  • vue+springboot如何实现登录验证码
    这篇文章主要介绍vue+springboot如何实现登录验证码,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!先看效果图在login页面添加验证码html在后端pom文件添加kaptcha依赖<dependenc...
    99+
    2023-06-15
  • springboot图片验证码功能模块怎么实现
    本篇内容主要讲解“springboot图片验证码功能模块怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springboot图片验证码功能模块怎么实现”吧!具体效果如下:工具类该工具类为生...
    99+
    2023-06-30
  • vue实现图形验证码登录
    本文实例为大家分享了vue实现图形验证码登录的具体代码,供大家参考,具体内容如下 1、效果图 2、在components下面新建文件identify.vue,内容: <t...
    99+
    2024-04-02
  • php怎么实现图片验证码
    本文操作环境:Windows7系统、PHP7.1版,DELL G3电脑。php怎么实现图片验证码?PHP实现图片验证码功能验证码: captcha, 是一种用于区别人和电脑的技术原理(Completely Automated Public ...
    99+
    2017-09-20
    php
  • 怎么用Springboot +redis+Kaptcha实现图片验证码功能
    这篇文章主要介绍了怎么用Springboot +redis+Kaptcha实现图片验证码功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用Springboot +redis+Kaptc...
    99+
    2023-06-29
  • vue实现登录时图形验证码
    本文实例为大家分享了vue实现登录时图形验证码的具体代码,供大家参考,具体内容如下 效果图: 点击图案可以切换字符 1.新建 Identify.vue 组件 <templat...
    99+
    2024-04-02
  • springboot怎么集成easy-captcha实现图像验证码显示和登录
    这篇文章主要介绍“springboot怎么集成easy-captcha实现图像验证码显示和登录”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“springboot怎么集成easy-captcha实现图...
    99+
    2023-07-05
  • php怎么实现密码登录验证
    在PHP中,可以使用以下步骤来实现密码登录验证:1. 创建一个HTML表单,包含一个用户名输入框和一个密码输入框。用户输入用户名和密...
    99+
    2023-10-10
    php
  • java实现图片验证码
    本文实例为大家分享了java实现图片验证码的具体代码,供大家参考,具体内容如下 目的: 1) 验证操作者是否是人 2) 防止表单重复提交 生成验证码的要点: 1) 使用java代码生...
    99+
    2024-04-02
  • SpringBoot整合kaptcha实现图片验证码功能
    目录栗子配置文件SpringBoot项目中pom.xml文件项目代码项目结构SpringBootVerifyCodeApplication.javaVerifyCodeConfig....
    99+
    2024-04-02
  • vue实现登录验证码
    本文实例为大家分享了vue实现登录验证码的具体代码,供大家参考,具体内容如下 先来demo效果图 canvas验证码组件(可直接复制,无需改动) <template>...
    99+
    2024-04-02
  • Android实现验证码登录
    本文实例为大家分享了Android实现验证码登录的具体代码,供大家参考,具体内容如下 结果展示 1.导包 1.1在项目的gradle中导入 maven { url "https...
    99+
    2024-04-02
  • python爬虫模拟登录之图片验证码实现详解
    我们在用爬虫对门户网站进行模拟登录是总会有输入图片验证码的,例如这种 那我们怎么解决这个问题实现全自动的模拟登录呢?只要思想不滑坡,办法总比困难多。我这里使用的是百度智能云里面的文...
    99+
    2024-04-02
  • 登录校验之滑块验证码完整实现(vue + springboot)
    文章目录 前言一、实现效果二、实现思路三、实现步骤1. 后端 java 代码1.1 新建一个拼图验证码类1.2 新建一个拼图验证码工具类1.3 新建一个 service 类1.4 新建一个 controller 类1.5 登录接口 ...
    99+
    2023-08-18
    vue.js spring boot java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作