~接上篇~SpringSecurity配置验证码

导入依赖

		<dependency>
            <groupId>com.github.axet</groupId>
            <artifactId>kaptcha</artifactId>
            <version>0.0.9</version>
        </dependency>

添加验证码的配置信息

kaptcha.properties

# 验证码配置
kaptcha.border=no
kaptcha.border.color=105,179,90
kaptcha.image.width=100
kaptcha.image.height=45
kaptcha.session.key=code
kaptcha.textproducer.font.color=blue
kaptcha.textproducer.font.size=35
kaptcha.textproducer.char.length=4
kaptcha.textproducer.font.names=\u5B8B\u4F53,\u6977\u4F53,\u5FAE\u8F6F\u96C5\u9ED1

验证码过期时间

CaptchaImageModel

package com.admin.model;

import java.time.LocalDateTime;

/**
 * @version 1.0
 * @Author 张云飞
 * @Date 2021/10/6 0006 15:20
 * @注释 验证码过期时间
 */
public class CaptchaImageModel {

    private String code;

    private LocalDateTime expireTime;


    public CaptchaImageModel(String code, int expireAfterSeconds){
        this.code = code;
        this.expireTime = LocalDateTime.now().plusSeconds(expireAfterSeconds);
    }

    public String getCode() {
        return code;
    }

    /**
     * 验证码是否失效
     * @return
     */
    public boolean isExpired(){
        return  LocalDateTime.now().isAfter(expireTime);
    }
}

controller层


package com.admin.controller;

import com.admin.model.CaptchaImageModel;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * @version 1.0
 * @Author 张云飞
 * @Date 2021/10/6 0006 15:15
 * @注释
 */
@RestController
public class CaptchaController {

    @Resource
    private DefaultKaptcha defaultKaptcha;

    @RequestMapping("/image")
    public void kaptcha(HttpSession session, HttpServletResponse response) throws IOException {
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        // 验证码文字
        String capText = defaultKaptcha.createText();
        // 将验证码存入session 并设置2分钟后过期
        session.setAttribute("captcha_key", new CaptchaImageModel(capText, 2 * 60));
        ServletOutputStream out = response.getOutputStream();
        BufferedImage bufferedImage = defaultKaptcha.createImage(capText);
        ImageIO.write(bufferedImage, "jpg", out);
        //刷新
        out.flush();
    }

}

验证码校验使用过滤器来完成,在配置类中加入过滤器

CaptchaCodeFilter

package com.admin.filters;

import com.admin.model.CaptchaImageModel;
import com.admin.model.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

/**
 * @version 1.0
 * @Author 张云飞
 * @Date 2021/10/6 0006 15:42
 * @注释
 */
@Component
public class CaptchaCodeFilter extends OncePerRequestFilter {

    private static ObjectMapper objectMapper=new ObjectMapper();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //只有在登录请求时才有验证码过滤操作
        if (StringUtils.equals("/login",request.getRequestURI()) && StringUtils.equalsIgnoreCase(request.getMethod(),"post")){
            //校验登录验证码是否正确
            try {
                this.validate(new ServletWebRequest(request));
            } catch (AuthenticationException e) {
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(objectMapper.writeValueAsString(
                        Result.error("验证码错误")
                ));
                return;
            }
        }
        filterChain.doFilter(request,response);
    }

    private void validate(ServletWebRequest request) throws ServletRequestBindingException {
        HttpSession session = request.getRequest().getSession();
        //获取请求中参数值
        String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "captchaCode");
        if (StringUtils.isEmpty(codeInRequest)){
            throw new SessionAuthenticationException("验证码不能为空");
        }

        //拿到图片的session
        CaptchaImageModel codeInSession= (CaptchaImageModel) session.getAttribute("captcha_key");
        if (Objects.isNull(codeInSession)){
            throw new SessionAuthenticationException("验证码不存在");
        }

        //判断过期
        if (codeInSession.isExpired()){
            throw new SessionAuthenticationException("验证码过期");
        }

        //判断验证码是否正确
        if (!(StringUtils.equals(codeInSession.getCode(),codeInRequest))){
            throw new SessionAuthenticationException("验证码不匹配");
        }
    }
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务