在spring security中,可以結(jié)合jcaptcha進(jìn)行使用,具體方法如下:
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驗(yàn)證碼圖片生成引擎, 仿照J(rèn)Captcha2.0編寫類似GMail驗(yàn)證碼的樣式.
- */
- public class GMailEngine extends ListImageCaptchaEngine {
-
- @Override
- protected void buildInitialFactories() {
-
- // 圖片和字體大小設(shè)置
- 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));
- }
-
- }
過(guò)濾器如下:
- 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;
-
- /**
- * 針對(duì) JCaptcha 專門的過(guò)濾器(Filter)
- *
- */
- public class JCaptchaFilter implements Filter {
-
- // web.xml中的參數(shù)名定義
- 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";
-
- // 默認(rèn)值定義
- 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回調(diào)初始化函數(shù).
- */
- 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為驗(yàn)證處理請(qǐng)求,其余為生成驗(yàn)證圖片請(qǐng)求.
- if (StringUtils.startsWith(servletPath, filterProcessesUrl)) {
- boolean validated = validateCaptchaChallenge(request);
- if (validated) {
- chain.doFilter(request, response);
- } else {
- redirectFailureUrl(request, response);
- }
- } else {
- genernateCaptchaImage(request, response);
- }
- }
-
- /**
- * Filter回調(diào)退出函數(shù).
- */
- 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參數(shù)");
- }
-
- 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實(shí)例.
- */
- protected void initCaptchaService(final FilterConfig fConfig) {
-
- ApplicationContext context = WebApplicationContextUtils
- .getWebApplicationContext(fConfig.getServletContext());
- captchaService = (CaptchaService) context.getBean(captchaServiceId);
- }
-
- /**
- * 生成驗(yàn)證碼圖片.
- */
- 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();
- }
- }
- }
-
- /**
- * 驗(yàn)證驗(yàn)證碼.
- */
- protected boolean validateCaptchaChallenge(final HttpServletRequest request) {
-
- try {
-
- String captchaID = request.getSession().getId();
- String challengeResponse = request
- .getParameter(captchaParamterName);
- // 自動(dòng)通過(guò)值存在時(shí),檢驗(yàn)輸入值是否等于自動(dòng)通過(guò)值
- if (StringUtils.isNotBlank(autoPassValue)&& autoPassValue.equals(challengeResponse)) {
-
- return true;
- }
-
- return captchaService.validateResponseForID(captchaID,challengeResponse);
- } catch (CaptchaServiceException e) {
- logger.error(e.getMessage(), e);
- return false;
- }
- }
-
- /**
- * 跳轉(zhuǎn)到失敗頁(yè)面.
- *
- * 可在子類進(jìn)行擴(kuò)展, 比如在session中放入SpringSecurity的Exception.
- */
- protected void redirectFailureUrl(final HttpServletRequest request,final HttpServletResponse response) throws IOException {
-
- response.sendRedirect(request.getContextPath() + failureUrl);
- }
-
- /**
- * 設(shè)置禁止客戶端緩存的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./2001/XMLSchema-instance" xmlns="http://java./xml/ns/javaee" xmlns:web="http://java./xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java./xml/ns/javaee http://java./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默認(rèn)刷新Log4j配置文件的間隔,單位為millisecond,可以不設(shè)置 -->
- <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>
-
- <!--******************************** -->
- <!--*******字符集 過(guò)濾器************ -->
- <!--******************************* -->
- <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./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>密 碼:</td>
- <td>
- <input class = "login-smallInput" type='password' name='j_password' />
- </td>
- </tr>
- <tr>
- <td>驗(yàn)證碼:</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>
|