SSM集成SpringSecurity(十)自定义过滤器实现验证码检查

很多系统进行登录的时候,都会要求用户输入验证码。我们可以让springSecurity在进行用户密码校验之前进行验证码的校验,验证码验证通过再进行用户密码的校验。我们需要自定义过滤器。

1: 在jsp目录下新增一个imageCode.jsp文件,该文件用于生成验证码

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@ page import="java.util.Random"%>

<%@ page import="java.io.OutputStream"%>

<%@ page import="java.awt.Color"%>

<%@ page import="java.awt.Font"%>

<%@ page import="java.awt.Graphics"%>

<%@ page import="java.awt.image.BufferedImage"%>

<%@ page import="javax.imageio.ImageIO"%>

<%

int width = 80;

int height = 32;

//create the image

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics g = image.getGraphics();

// set the background color

g.setColor(new Color(0xDCDCDC));

g.fillRect(0, 0, width, height);

// draw the border

g.setColor(Color.black);

g.drawRect(0, 0, width - 1, height - 1);

// create a random instance to generate the codes

Random rdm = new Random();

String hash1 = Integer.toHexString(rdm.nextInt());

// make some confusion

for (int i = 0; i < 50; i++) {

int x = rdm.nextInt(width);

int y = rdm.nextInt(height);

g.drawOval(x, y, 0, 0);

}

// generate a random code

String capstr = hash1.substring(0, 4);

session.setAttribute("key", capstr);

g.setColor(new Color(0, 100, 0));

g.setFont(new Font("Candara", Font.BOLD, 24));

g.drawString(capstr, 8, 24);

g.dispose();

response.setContentType("image/jpeg");

out.clear();

out = pageContext.pushBody();

OutputStream strm = response.getOutputStream();

ImageIO.write(image, "jpeg", strm);

strm.close();

%>

login.jsp文件修改增加下面代码,用于显示验证码

<input type="text" name="imageCode"/><img src="${pageContext.request.contextPath}/imageCode"><br>

MainController中增加下面方法

@RequestMapping("/imageCode")

public String imageCode() {

return "imageCode";

}

2:自定义验证码过滤器ImageCodeAuthenticationFilter,在security包下新增ImageCodeAuthenticationFilter类。

package com.xhc.security;

import org.springframework.security.core.AuthenticationException;

import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import org.springframework.util.StringUtils;

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;

/**

*

*/

public class ImageCodeAuthenticationFilter extends OncePerRequestFilter {

private AuthenticationFailureHandler authenticationFailureHandler;

public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {

this.authenticationFailureHandler = authenticationFailureHandler;

}

@Override

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

//判断当前请求 是否为登录请求

if( request.getRequestURI().contains("/securityLogin") ){

//校验验证码

try {

//获取用户输入的验证码

final String imageCode = request.getParameter("imageCode");

//获取系统生成的验证码

String key = (String)request.getSession().getAttribute("key");

if(StringUtils.isEmpty(imageCode.trim())){

throw new ImageCodeException( "验证码必须输入");

}

if(!imageCode.trim().equals(key.trim())){

throw new ImageCodeException( "验证码不一致");

}

}catch (AuthenticationException e){

//交给自定义AuthentFailureHandler处理

authenticationFailureHandler.onAuthenticationFailure(request,response,e);

return;

}

}

filterChain.doFilter(request,response);

}

}

同时也在security包下自定义一个验证码的异常处理类ImageCodeException

package com.xhc.security;

import org.springframework.security.core.AuthenticationException;

public class ImageCodeException extends AuthenticationException {

public ImageCodeException(String msg, Throwable t) {

super(msg, t);

}

public ImageCodeException(String msg) {

super(msg);

}

}

3: 修改spring-security.xml文件,在下面添加

<bean id="imageCodeAuthenticationFilter" class="com.xhc.security.ImageCodeAuthenticationFilter">

<property name="authenticationFailureHandler" ref="myAuthenticationFailureHandler"/>

</bean>

在security-form标签前添加

<!-- 自定义验证码过滤器,在表单登录之前调用 -->

<security:custom-filter ref="imageCodeAuthenticationFilter" before="FORM_LOGIN_FILTER"/>

4: 启动项目,输入验证码进行登录,到这里就ok了。

发布了39 篇原创文章 · 获赞 33 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/love1793912554/article/details/104298677