This article introduces SpringBoot combined with SpringSecurity to implement the graphical verification code function, and shares it with you, as follows:
Generate graphic verification code
The process of generating graphic verification codes is relatively simple and has nothing to do with SpringSecurity. So I just posted the code
Generate pictures based on random numbers
/** * Generate graphic verification code* @param request * @return */private ImageCode generate(ServletWebRequest request) { int width = 64; int height = 32; 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);}/** * Generate random background stripes* * @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);}Save random numbers in Session&& Write the generated image to the interface response
@RestControllerpublic class ValidateCodeController { 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 = generate(new ServletWebRequest(request)); sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode); ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream()); }}Add graphic verification code to the authentication process
In the detailed explanation of the SpringSecurity authentication process, we mentioned that SpringSecurity is verified through the filter chain. We want to verify the graphic verification code, so we can verify it before the authentication process, that is, before UsernamePasswordAuthenticationFilter .
Custom graphic verification code filter
@Componentpublic class ValidateCodeFilter extends OncePerRequestFilter { private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy(); private AuthenticationFailureHandler authenticationFailureHandler; @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { if(StringUtils.equals("/user/login", httpServletRequest.getRequestURI()) && StringUtils.equalsIgnoreCase(httpServletRequest.getMethod(), "post")) { try { // 1. Verify verification of verification code(new ServletWebRequest(httpServletRequest)); } catch (ValidateCodeException e) { // 2. If the verification fails, call SpringSecurity's verification failure processor authenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, e); return ; } } // 3. If the verification is passed, release filterChain.doFilter(httpServletRequest, httpServletResponse); }}The verification code verification process here is relatively simple. It mainly determines whether the passed parameters are consistent with the stored ones in the Session, and whether the verification code in the Session has expired.
After having our own verification code filter, we also need to configure it before UsernamePasswordAuthenticationFilter:
@Overrideprotected void configure(HttpSecurity http) throws Exception { ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter(); validateCodeFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler); // Configure our custom filters to UsernamePasswordAuthenticationFilter before http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) .formLogin() // Define the login page to which the user needs to log in. // The subsequent configuration is omitted}Code download
Spring-Security
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.