`

spring security进级篇VI JCaptcha验证编码的使用

 
阅读更多

在spring security中,可以结合jcaptcha进行使用,具体方法如下:

1.java类如下:

package com.spring.security.jcaptcha;

import java.awt.Color;
import java.awt.Font;
import java.awt.image.ImageFilter;

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import com.octo.captcha.component.image.color.RandomListColorGenerator;
import com.octo.captcha.component.image.deformation.ImageDeformation;
import com.octo.captcha.component.image.deformation.ImageDeformationByFilters;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.FileDictionary;
import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;

/**
 * JCaptcha验证码图片生成引擎, 仿照JCaptcha2.0编写类似GMail验证码的样式.
 */
public class GMailEngine extends ListImageCaptchaEngine {

	@Override
	protected void buildInitialFactories() {

		// 图片和字体大小设置
		int minWordLength = 4;
		int maxWordLength = 5;
		int fontSize = 20;
		int imageWidth = 100;
		int imageHeight = 36;

		WordGenerator dictionnaryWords = new ComposeDictionaryWordGenerator(
				new FileDictionary("toddlist"));

		// word2image components
		TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
				maxWordLength, new RandomListColorGenerator(new Color[] {
						new Color(23, 170, 27), new Color(220, 34, 11),
						new Color(23, 67, 172) }), new TextDecorator[] {});
		BackgroundGenerator background = new UniColorBackgroundGenerator(
				imageWidth, imageHeight, Color.white);
		FontGenerator font = new RandomFontGenerator(fontSize, fontSize,
				new Font[] { new Font("nyala", Font.BOLD, fontSize),
						new Font("Bell MT", Font.PLAIN, fontSize),
						new Font("Credit valley", Font.BOLD, fontSize) });
		
		ImageDeformation postDef = new ImageDeformationByFilters(
				new ImageFilter[] {});
		ImageDeformation backDef = new ImageDeformationByFilters(
				new ImageFilter[] {});
		ImageDeformation textDef = new ImageDeformationByFilters(
				new ImageFilter[] {});

		WordToImage word2image = new DeformedComposedWordToImage(font,
				background, randomPaster, backDef, textDef, postDef);
		
		addFactory(new GimpyFactory(dictionnaryWords, word2image));
	}

}

 

过滤器如下:

package com.spring.security.jcaptcha;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.octo.captcha.service.CaptchaService;
import com.octo.captcha.service.CaptchaServiceException;

/**
 * 针对 JCaptcha 专门的过滤器(Filter)
 * 
 */
public class JCaptchaFilter implements Filter {

	// web.xml中的参数名定义
	public static final String PARAM_CAPTCHA_PARAMTER_NAME = "captchaParamterName";
	public static final String PARAM_CAPTCHA_SERVICE_ID = "captchaServiceId";
	public static final String PARAM_FILTER_PROCESSES_URL = "filterProcessesUrl";
	public static final String PARAM_FAILURE_URL = "failureUrl";
	public static final String PARAM_AUTO_PASS_VALUE = "autoPassValue";

	// 默认值定义
	public static final String DEFAULT_FILTER_PROCESSES_URL = "/j_spring_security_check";
	public static final String DEFAULT_CAPTCHA_SERVICE_ID = "captchaService";
	public static final String DEFAULT_CAPTCHA_PARAMTER_NAME = "j_captcha";

	protected static Logger logger = Logger.getLogger("service");

	private String failureUrl;
	private String filterProcessesUrl = DEFAULT_FILTER_PROCESSES_URL;
	private String captchaServiceId = DEFAULT_CAPTCHA_SERVICE_ID;
	private String captchaParamterName = DEFAULT_CAPTCHA_PARAMTER_NAME;
	private String autoPassValue;

	private CaptchaService captchaService;

	/**
	 * Filter回调初始化函数.
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
		initParameters(filterConfig);
		initCaptchaService(filterConfig);
	}

	public void doFilter(ServletRequest theRequest,ServletResponse theResponse, FilterChain chain) throws IOException,
			ServletException {
		
		HttpServletRequest request = (HttpServletRequest) theRequest;
		HttpServletResponse response = (HttpServletResponse) theResponse;
		String servletPath = request.getServletPath();
		
		// 符合filterProcessesUrl为验证处理请求,其余为生成验证图片请求.
		if (StringUtils.startsWith(servletPath, filterProcessesUrl)) {
			boolean validated = validateCaptchaChallenge(request);
			if (validated) {
				chain.doFilter(request, response);
			} else {
				redirectFailureUrl(request, response);
			}
		} else {
			genernateCaptchaImage(request, response);
		}
	}

	/**
	 * Filter回调退出函数.
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * 初始化web.xml中定义的filter init-param.
	 */
	protected void initParameters(final FilterConfig fConfig) {
		
		if (StringUtils.isBlank(fConfig.getInitParameter(PARAM_FAILURE_URL))) {
			throw new IllegalArgumentException("CaptchaFilter缺少failureUrl参数");
		}

		failureUrl = fConfig.getInitParameter(PARAM_FAILURE_URL);

		if (StringUtils.isNotBlank(fConfig
				.getInitParameter(PARAM_FILTER_PROCESSES_URL))) {
			filterProcessesUrl = fConfig
					.getInitParameter(PARAM_FILTER_PROCESSES_URL);
		}

		if (StringUtils.isNotBlank(fConfig
				.getInitParameter(PARAM_CAPTCHA_SERVICE_ID))) {
			captchaServiceId = fConfig
					.getInitParameter(PARAM_CAPTCHA_SERVICE_ID);
		}

		if (StringUtils.isNotBlank(fConfig
				.getInitParameter(PARAM_CAPTCHA_PARAMTER_NAME))) {
			captchaParamterName = fConfig
					.getInitParameter(PARAM_CAPTCHA_PARAMTER_NAME);
		}

		if (StringUtils.isNotBlank(fConfig
				.getInitParameter(PARAM_AUTO_PASS_VALUE))) {
			autoPassValue = fConfig.getInitParameter(PARAM_AUTO_PASS_VALUE);
		}
	}

	/**
	 * 从ApplicatonContext获取CaptchaService实例.
	 */
	protected void initCaptchaService(final FilterConfig fConfig) {
		
		ApplicationContext context = WebApplicationContextUtils
				.getWebApplicationContext(fConfig.getServletContext());
		captchaService = (CaptchaService) context.getBean(captchaServiceId);
	}

	/**
	 * 生成验证码图片.
	 */
	protected void genernateCaptchaImage(final HttpServletRequest request,
			final HttpServletResponse response) throws IOException {

		setDisableCacheHeader(response);
		response.setContentType("image/jpeg");

		ServletOutputStream out = response.getOutputStream();
		try {
			String captchaId = request.getSession(true).getId();
			BufferedImage challenge = (BufferedImage) captchaService
					.getChallengeForID(captchaId, request.getLocale());
			ImageIO.write(challenge, "jpg", out);
			out.flush();
		} catch (CaptchaServiceException e) {
			logger.error(e.getMessage(), e);
		} finally {
			if(out!=null){
				out.close();
			}
		}
	}

	/**
	 * 验证验证码.
	 */
	protected boolean validateCaptchaChallenge(final HttpServletRequest request) {
		
		try {
			
			String captchaID = request.getSession().getId();
			String challengeResponse = request
					.getParameter(captchaParamterName);
			// 自动通过值存在时,检验输入值是否等于自动通过值
			if (StringUtils.isNotBlank(autoPassValue)&& autoPassValue.equals(challengeResponse)) {
				
				return true;
			}
			
			return captchaService.validateResponseForID(captchaID,challengeResponse);
		} catch (CaptchaServiceException e) {
			logger.error(e.getMessage(), e);
			return false;
		}
	}

	/**
	 * 跳转到失败页面.
	 * 
	 * 可在子类进行扩展, 比如在session中放入SpringSecurity的Exception.
	 */
	protected void redirectFailureUrl(final HttpServletRequest request,final HttpServletResponse response) throws IOException {
		
		response.sendRedirect(request.getContextPath() + failureUrl);
	}

	/**
	 * 设置禁止客户端缓存的Header.
	 */
	public static void setDisableCacheHeader(HttpServletResponse response) {
		// Http 1.0 header
		response.setDateHeader("Expires", 1L);
		response.addHeader("Pragma", "no-cache");
		// Http 1.1 header
		response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
	}
}

 

web.xml 配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>springSecurityIII</display-name>
  
	<!--******************************** -->
	<!--*******log4j日志信息的配置****** -->
	<!--******************************* -->
	<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>classpath:log4j.xml</param-value>
	</context-param>
	<!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond,可以不设置 -->
	<context-param>
		<param-name>log4jRefreshInterval</param-name>
		<param-value>60000</param-value>
	</context-param>

	<!--******************************** -->
	<!--*******spring bean的配置******** -->
	<!--******************************* -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
	</listener>
	
	<!--******************************** -->
	<!--*******字符集 过滤器************ -->
	<!--******************************* -->
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--******************************** -->
	<!--*******session的配置************ -->
	<!--******************************* -->
	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
	
  <filter>
    <filter-name>jcaptchaFilter</filter-name>
    <filter-class>com.spring.security.jcaptcha.JCaptchaFilter</filter-class>
    <init-param>
      <param-name>failureUrl</param-name>
      <param-value>/login.jsp</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>jcaptchaFilter</filter-name>
    <url-pattern>/jcaptcha.jpg</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>jcaptchaFilter</filter-name>
    <url-pattern>/j_spring_security_check</url-pattern>
  </filter-mapping>
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
  </listener>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 

login.jsp

 

<%@ include file="/common/taglibs.jsp"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登 录</title>
<script type="text/javascript">

/*==============================================
*	refreash the captcha to general new picture
*==============================================*/
function refreshCaptcha() {   
	$('#captchaImg').hide().attr(   
	'src',   
	'<c:url value="/jcaptcha.jpg"/>' + '?' + Math.floor(Math.random() * 100)).fadeIn();   
}
</script>
</head>
<body>
	<center>
		<div class="login-error">
			${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
		</div>
		<form action="${pageContext.request.contextPath}/j_spring_security_check" method="post">
			<table style="width: 60%">
				<tr>
					<td>用户名:</td>
					<td>
						<input class = "login-smallInput" type='text' name='j_username'/>
					</td>
				</tr>
				<tr>
					<td>密 &nbsp;&nbsp;码:</td>
					<td>
						<input class = "login-smallInput" type='password' name='j_password' />
					</td>
				</tr>
				<tr>
					<td>验证码:</td>
					<td>
						<input type='text' name='j_captcha' size="5"/> 
						<img id="captchaImg" style="vertical-align:middle" src="<c:url value="/jcaptcha.jpg"/>" /> 
						<a href="javascript:refreshCaptcha()">看不清楚换一张</a>
					</td>
				</tr>
				<tr>
					<td>
						<input id="_spring_security_remember_me" name="_spring_security_remember_me" type="checkbox"/>
					</td>
					<td>
						<label for="_spring_security_remember_me">Remember Me?</label>
					</td>
				</tr>
				<tr>
					<td colspan="2">
						<input type="submit" name="submit" value="登录" />
					</td>
				</tr>
			</table>
		</form>
	</center>
</body>
</html>

 

分享到:
评论

相关推荐

    spring security进级篇 V 自定义标签控制显示

    在IT领域,Spring Security是一个广泛使用的安全框架,用于保护基于Java的应用程序。这篇"Spring Security进阶篇 V 自定义标签控制显示"的博客文章显然深入探讨了如何在Spring Security中实现自定义的安全控制,以便...

    Spring Security in Action

    Spring Security 是一个基于 Java 的安全框架,旨在提供身份验证、授权和访问控制等功能。下面是 Spring Security 的主要知识点: 一、身份验证(Authentication) 身份验证是指对用户身份的验证,以确保用户的...

    spring boot3.x结合spring security最新版实现jwt登录验证

    本教程将详细讲解如何在Spring Boot 3.x版本中结合Spring Security的最新版实现JWT(JSON Web Token)登录验证。 首先,让我们了解JWT。JWT是一种轻量级的身份认证和授权机制,它以JSON对象的形式在客户端和服务器...

    Spring Security 资料合集

    Spring Security 是一个强大的安全框架,主要用于Java应用的安全管理,它为Web应用和企业级应用提供了全面的安全服务。这个框架能够处理认证、授权以及各种安全相关的功能,帮助开发者构建安全、可扩展的应用。以下...

    SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)

    SpringBoot+SpringSecurity处理Ajax登录请求问题是SpringBoot开发中的一個常见问题,本文将详细介绍如何使用SpringBoot+SpringSecurity处理Ajax登录请求问题。 知识点1:SpringBoot+SpringSecurity框架简介 ...

    spring security 完整项目实例

    Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...

    springsecurity学习笔记

    8. **表达式语言(SpEL)**:Spring Security 使用Spring Expression Language(SpEL)来定义访问控制规则,允许开发者用更灵活的方式定义谁可以访问什么。 在"springsecurity学习笔记"中,你可能会涉及以下主题: ...

    springsecurity3和JCaptcha的整合 验证码

    springsecurity3和JCaptcha的整合 验证码

    自定义Spring Security的身份验证失败处理方法

    这篇文章将展示如何自定义 Spring Security 的身份验证失败处理方法,并且提供了相关的知识点和技术细节。 一、概述 在本篇文章中,我们将展示如何在 Spring Boot 应用程序中自定义 Spring Security 的身份验证...

    spring-security 官方文档 中文版

    ### Spring Security 官方文档中文版重要知识点解析 #### 一、Spring Security 概述 **1.1 Spring Security ...无论是构建企业级应用还是个人项目,掌握 Spring Security 的使用都将极大地提升应用的安全性和可靠性。

    Spring Cloud Gateway 整合 Spring Security 统一登录认证鉴权

    而Spring Security 则是 Java 开发中广泛使用的安全框架,用于实现认证和授权。当我们将这两者结合时,我们可以创建一个强大的统一登录认证鉴权系统。 首先,让我们深入了解Spring Cloud Gateway。这是一个基于...

    SpringSecurity学习总结源代码

    SpringSecurity是Java开发中用于构建安全Web应用的框架,它提供了强大的身份验证、授权和访问控制功能。在本文中,我们将深入探讨SpringSecurity的核心概念、关键组件以及如何配置和使用这个框架。 首先,Spring...

    spring security 官方文档

    总之,Spring Security是Java开发者在构建安全应用程序时的重要工具,其强大的功能和灵活性使其成为企业级应用的理想选择。无论你是初学者还是经验丰富的开发者,官方文档都是学习和掌握Spring Security不可或缺的...

    SpringSecurity笔记,编程不良人笔记

    在本笔记中,我们将深入探讨SpringSecurity的核心概念、配置以及如何与SpringBoot结合使用。 1. **SpringSecurity核心概念** - **Filter Chain**: SpringSecurity通过一系列过滤器实现其安全功能,这些过滤器构成...

    spring security3 中文版本

    Spring Security 是一个强大的、高度可定制的身份验证和访问控制框架。它提供了许多功能,包括登录表单、记住我功能、多身份验证器、基于注解的安全配置、CSRF 防护、OAuth2 客户端和服务端支持等。Spring Security ...

    springSecurity 实现传参

    在这个场景中,我们关注的是如何使用Spring Security实现登录验证以及在登录过程中传递参数,特别是记录并返回用户登录前的页面。我们将深入探讨这个过程,并结合MySQL数据库的使用。 首先,让我们了解Spring ...

    最详细Spring Security学习资料(源码)

    Spring Security是一个功能强大且高度可定制的身份验证和授权框架,专门用于保护Java应用程序的安全性。它构建在Spring Framework基础之上,提供了全面的安全解决方案,包括身份验证、授权、攻击防护等功能。 Spring...

    spring spring security2.5 jar

    Spring Security是Spring生态体系中的一个核心组件,主要负责应用程序的安全性,包括认证和授权。它为Web应用提供了全面的保护,防止未经授权的访问和操作。在版本2.5时,Spring Security已经是一个成熟且功能丰富的...

    Spring Security+OAuth2 精讲,打造企业级认证与授权

    本课程"Spring Security+OAuth2 精讲,打造企业级认证与授权"深入浅出地讲解了这两个框架的使用和集成,旨在帮助开发者构建安全、高效的应用系统。 Spring Security是Spring生态系统中的一个强大安全框架,它提供了...

Global site tag (gtag.js) - Google Analytics