SpringSecurity添加图形验证码认证实现

下面我来为你讲解SpringSecurity添加图形验证码认证实现的完整攻略。

1. 引入依赖

pom.xml文件中添加以下依赖:

<!--验证码依赖-->
<dependency>
    <groupId>com.github.axolo</groupId>
    <artifactId>image-verify-code-spring-boot-starter</artifactId>
    <version>1.0.4</version>
</dependency>

2. 配置验证码

application.properties文件中添加以下配置:

verify-code.enabled=true  # 启用验证码
verify-code.url-patterns=/login  # 验证码拦截的地址
verify-code.image.width=220  # 验证码图片宽度
verify-code.image.height=50  # 验证码图片高度
verify-code.number.chars=4   # 验证码字符数量
verify-code.string.chars=acdefhjkmnpqrstuvwxyz2345678 # 验证码字符源

3. 实现验证码校验逻辑

在实现了UserDetailsService接口的类中添加验证方法:

public void validateVerifyCode(HttpServletRequest request) {
    VerifyCode verifyCode = (VerifyCode) request.getSession().getAttribute(VerifyCode.VERIFY_CODE);
    if (verifyCode == null) {
        throw new AuthenticationServiceException("验证码不能为空");
    }
    String inputVerifyCode = request.getParameter("code");
    if (StringUtils.isBlank(inputVerifyCode)) {
        throw new AuthenticationServiceException("验证码不能为空");
    }
    if (!inputVerifyCode.equalsIgnoreCase(verifyCode.getCode())) {
        throw new AuthenticationServiceException("验证码错误");
    }
}

4. 自定义UsernamePasswordAuthenticationFilter

继承UsernamePasswordAuthenticationFilter,重写attemptAuthentication方法,实现验证码校验逻辑:

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (request.getMethod().equals("POST")) {
            validateVerifyCode(request);
        }
        return super.attemptAuthentication(request, response);
    }
}

5. 添加过滤器链

WebSecurityConfigurerAdapter的子类中配置自定义过滤器:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/css/**", "/js/**", "/fonts/**", "/index").permitAll()
            .antMatchers("/users/**").hasRole("ADMIN")
            .and()
            .formLogin()
            .loginPage("/login").failureUrl("/login-error");
}

@Bean
public CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
    CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
    filter.setAuthenticationSuccessHandler(new LoginSuccessHandler());
    filter.setAuthenticationFailureHandler(new LoginFailureHandler());
    filter.setFilterProcessesUrl("/login");
    filter.setAuthenticationManager(authenticationManagerBean());
    return filter;
}

示例1

@GetMapping("/login")
public String login() {
    return "login";
}

@PostMapping("/login")
public void doLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    try {
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        request.getSession().setAttribute("SPRING_SECURITY_LAST_EXCEPTION", null);
        Authentication authentication = authenticationManager.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        session.setAttribute("user", authentication.getPrincipal());
        response.sendRedirect("/");
    } catch (AuthenticationException e) {
        request.getSession().setAttribute("SPRING_SECURITY_LAST_EXCEPTION", e);
        response.sendRedirect("/login?error");
    }
}

示例2

public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if (savedRequest == null) {
            super.onAuthenticationSuccess(request, response, authentication);
            return;
        }
        response.sendRedirect(savedRequest.getRedirectUrl());
    }
}

以上是添加图形验证码认证实现的完整攻略,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringSecurity添加图形验证码认证实现 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • PHP Parse Error: syntax error, unexpected $end 错误的解决办法

    当PHP代码运行过程中发生了语法错误,导致编译器无法正确解析代码时,会出现“PHP Parse Error: syntax error, unexpected $end”错误。这一错误的出现会导致程序运行异常终止。本文将详细讲解此类错误的解决办法,帮助读者更好地理解和解决这种常见的错误。 原因分析 这种错误通常是由于编写代码时,存在以下几种问题导致的:1. …

    Java 2023年6月15日
    00
  • 如何突破PHP程序员的技术瓶颈分析

    如何突破PHP程序员的技术瓶颈分析 1. 确定技术瓶颈 首先,我们需要确定技术瓶颈是什么。通常来说,技术瓶颈可能来自以下几个方面: 编程能力 网络编程能力 数据库设计能力 项目经验 针对不同的问题,我们需要采取不同的解决方案。一般来说,我们可以通过下面的方式来做一些自我评估: 性能分析:使用工具,比如xhprof,Blackfire等,对PHP应用的性能进行…

    Java 2023年6月15日
    00
  • Eclipse快捷键 推荐10个最有用的快捷键

    下面是Eclipse快捷键的完整攻略: 1. 常用快捷键 在Eclipse中,一些常用的快捷键包括: Ctrl + S:保存当前文件 Ctrl + C、Ctrl + X、Ctrl + V:复制、剪切、粘贴 Ctrl + Z、Ctrl + Y:撤销、重做 Ctrl + F:查找 Ctrl + Shift + R:查找某个文件并打开 2. 推荐使用的快捷键 除了…

    Java 2023年6月15日
    00
  • Java中的同步与异步详细介绍

    Java中的同步与异步详细介绍 1. 同步 同步指的是在代码中有一个任务或操作正在进行时,它阻塞了其他任务或操作的执行,直到该任务或操作完成。在Java中,使用synchronized关键字实现同步。 1.1 synchronized关键字 synchronized关键字可以用于方法或代码块中,保证在同一时间只有一个线程可以访问这些代码。例: public …

    Java 2023年5月26日
    00
  • java-servlet-转发AND路径(详解)

    下面是对应的完整攻略: Java Servlet 转发和路径详解 什么是 Servlet 转发? Servlet 转发是指一个 Servlet 将请求转发到另一个 Servlet(或 JSP、HTML等)进行处理,并将处理结果返回给客户端。在转发时,客户端并不知道请求被转发到了哪里,所以转发时可以使用相对路径,不一定非得使用绝对路径。 Servlet 转发示…

    Java 2023年6月15日
    00
  • 浅谈Java中Spring Boot的优势

    浅谈Java中SpringBoot的优势 介绍 Spring Boot是一个基于Spring框架的开发、构建和运行应用的框架、工具集,它能够让开发者极少的配置和快速构建出现代化的基于Spring的企业应用程序。本文将深入探讨Spring Boot在Java应用程序开发中的优势。 优势 快速搭建项目 Spring Boot可以通过约定的方式快速地构建出一个标准…

    Java 2023年5月15日
    00
  • Java运算符的知识点与代码汇总

    Java运算符的知识点与代码汇总 1. 概述 Java运算符是Java语言中用于完成各种算数、关系和逻辑运算的符号。在Java程序中,运算符经常被用于各种运算表达式中,通过运算符可以组合复杂的逻辑表达式,完成各种数据计算和判断。本文将详细讲解Java运算符的知识点和一些常见的使用示例。 2. 分类 Java运算符可分为以下几类: 算术运算符 赋值运算符 自增…

    Java 2023年5月30日
    00
  • 通过Kettle自定义jar包供javascript使用

    下面就通过以下几个步骤来详细讲解如何通过Kettle自定义jar包供javascript使用: 编写自定义jar包 首先,我们需要编写一个自定义jar包,来供Kettle中的javascript脚本使用。在编写自定义jar包之前,我们需要先了解一些必要的知识: 自定义jar包需要包含一个类或多个类,这些类需要实现Kettle中定义的某个Java接口,目的是为…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部