首先,在你的web.xml里加入过滤器"Acegi Channel Processing Filter"如下:
<filter>
<filter-name>Acegi Channel Processing Filter</filter-name>
<filter-class>org.acegi security.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegi security.securechannel.ChannelProcessingFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi Channel Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第二步,在你的bean的配置文件中加入如下bean:
<bean id="channelProcessingFilter" class="org.acegi security.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager"><ref local="channelDecisionManager"/></property>
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/login.action=REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS
</value>
</property>
</bean>
channelProcessingFilter的filterInvocationDefinitionSource属性中定义了哪些url将被拦截(需要验证码 才能访问)
/login.action=REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS
指定当用户登录提交login.action时,需要验证码 ,一共有四种验证支持,如下:
REQUIRES_CAPTCHA_BELOW_AVERAGE_TIME_IN_MILLIS_REQUESTS AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor (处理程序)
REQUIRES_CAPTCHA_AFTER_THRESOLD_IN_MILLIS AlwaysTestAfterTimeInMillisCaptchaChannelProcessor
REQUIRES_CAPTCHA_ABOVE_THRESOLD_REQUESTS AlwaysTestAfterMaxRequestsCaptchaChannelProcessor
REQUIRES_CAPTCHA_ONCE_ABOVE_THRESOLD_REQUESTS TestOnceAfterMaxRequestsCaptchaChannelProcessor
我选择了第一种.
<bean id="channelDecisionManager" class="org.acegi security.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref local="alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor"/>
</list>
</property>
</bean>
<bean id="alwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor" class="org.acegi security.captcha.AlwaysTestBelowAverageTimeInMillisBetweenRequestsChannelProcessor">
<property name="thresold">
<value>20000</value>
</property>
<property name="entryPoint">
<ref bean="captchaEntryPoint" />
</property>
</bean>
<!-- captchaFormUrl属性指定了验证失败后页面的指向!!! -->
<bean id="captchaEntryPoint" class="org.acegi security.captcha.CaptchaEntryPoint">
<property name="captchaFormUrl">
<value>/index.action?login_error=2</value>
</property>
</bean>
captchaValidationProcessingFilter拦截了所有的http请求,如果请求中有名字为"j_captcha_response"的参数,将调用CaptchaServiceProxy 接口的实现类来进行验证码 图片的生成等操作.
<bean id="captchaValidationProcessingFilter" class="org.acegi security.captcha.CaptchaValidationProcessingFilter">
<property name="captchaService">
<ref bean="captchaService" />
</property>
<property name="captchaValidationParameter">
<value>j_captcha_response</value>
</property>
</bean>
<bean id="captchaService" class="com.demon.security.JCaptchaServiceProxyImpl" >
<property name="jcaptchaService" ref="jcaptchaService" />
</bean>
<!-- jcaptchaService指定了用于生成验证码 图片的类,不过这个生成的图片很难看,下面有一种生成自定义图片的方法-->
<bean id="jcaptchaService" class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService" />
接着更改filterChainProxy的filterInvocationDefinitionSource属性,按顺序加入captchaValidationProcessingFilter,channelProcessingFilter两个过滤器,如下:
<bean id="filterChainProxy" class="org.acegi security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter, captchaValidationProcessingFilter, channelProcessingFilter, logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
给httpSessionContextIntegrationFilter加入context属下如下:
<bean id="httpSessionContextIntegrationFilter" class="org.acegi security.context.HttpSessionContextIntegrationFilter">
<property name="context"><value>org.acegi security.captcha.CaptchaSecurityContextImpl</value></property>
</bean>
配置文件到此就结束了,然后是页面文件的登录表单
<s:form action="login.action" method="post">
<TABLE>
<td>请输入右边的验证码 </td>
<td><input type="text" name="j_captcha_response"/>
<img src="captcha-image.action"/></td>
</tr>
</TABLE>
</s:form>
因为我是用的stucts2做为mvc框架,把作为验证码 的img标签的src指定为"captcha-image.action",
然后在struct.xml配置相应的action如下:
<action name="captcha-image" class="com.demon.security.CaptchaImageCreateController"/>
即当页面加载时,会执行CaptchaImageCreateController类,代码如下:
package com.demon.security;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.InitializingBean;
import com.opensymphony.xwork2.ActionSupport;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
@SuppressWarnings("serial")
public class CaptchaImageCreateController extends ActionSupport implements InitializingBean {
private ImageCaptchaService jcaptchaService;
public String execute() throws Exception{
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
byte[] captchaChallengeAsJpeg = null;
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
String captchaId = request.getSession().getId();
//生成验证码 图片,在这里我们只需要在spring的bean配置文件中更改jcaptchaService的实现,就可以生成不同的验证码 图片
BufferedImage challenge = jcaptchaService.getImageChallengeForID(captchaId,request.getLocale());
JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = response.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
return null;
}
public void setJcaptchaService(ImageCaptchaService jcaptchaService) {
this.jcaptchaService = jcaptchaService;
}
public void afterPropertiesSet() throws Exception {
if(jcaptchaService == null){
throw new RuntimeException("Image captcha service wasn`t set!");
}
}
}
OK!!!!!!!!!!!!!!
##########################################################################
由于<bean id="jcaptchaService" class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService" />
生成的图片确实比较丑,可以更改为以下实现:
<bean id="jcaptchaService" class="com.octo.captcha.service.multitype.GenericManageableCaptchaService">
<constructor-arg index="0"><ref bean="imageEngine"/></constructor-arg>
<constructor-arg index="1"><value>180</value></constructor-arg>
<constructor-arg index="2"><value>180000</value></constructor-arg>
</bean>
<bean id="imageEngine" class="com.octo.captcha.engine.GenericCaptchaEngine">
<constructor-arg index="0">
<list>
<ref bean="CaptchaFactory"/>
</list>
</constructor-arg>
</bean>
<bean id="CaptchaFactory" class="com.octo.captcha.image.gimpy.GimpyFactory" >
<constructor-arg><ref bean="wordgen"/></constructor-arg>
<constructor-arg><ref bean="wordtoimage"/></constructor-arg>
</bean>
<bean id="wordgen" class= "com.octo.captcha.component.word.wordgenerator.DictionaryWordGenerator" >
<constructor-arg><ref bean="filedict"/></constructor-arg>
</bean>
<bean id="wordtoimage" class="com.octo.captcha.component.image.wordtoimage.ComposedWordToImage" >
<constructor-arg index="0"><ref bean="fontGenRandom"/></constructor-arg>
<constructor-arg index="1"><ref bean="backGenUni"/></constructor-arg>
<constructor-arg index="2"><ref bean="simpleWhitePaster"/></constructor-arg>
</bean>
<bean id="filedict" class="com.octo.captcha.component.word.FileDictionary" >
<constructor-arg index="0"><value>toddlist</value></constructor-arg>
</bean>
<bean id="fontGenRandom" class="com.octo.captcha.component.image.fontgenerator.RandomFontGenerator" >
<!-- 验证码 字体最小值 -->
<constructor-arg index="0"><value>20</value></constructor-arg>
<!-- 验证码 字体最大值 -->
<constructor-arg index="1"><value>20</value></constructor-arg>
<constructor-arg index="2">
<list>
<ref bean="fontArial"/>
</list>
</constructor-arg>
</bean>
<bean id="fontArial" class="java.awt.Font" >
<constructor-arg index="0"><value>Arial</value></constructor-arg>
<constructor-arg index="1"><value>0</value></constructor-arg>
<constructor-arg index="2"><value>10</value></constructor-arg>
</bean>
<bean id="backGenUni" class="com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator" >
<!-- 验证码 图片长度 -->
<constructor-arg index="0"><value>80</value></constructor-arg>
<!-- 验证码 图片高度 -->
<constructor-arg index="1"><value>25</value></constructor-arg>
</bean>
<bean id="simpleWhitePaster" class="com.octo.captcha.component.image.textpaster.SimpleTextPaster" >
<!-- 验证码 个数最小值 -->
<constructor-arg type="java.lang.Integer" index="0">
<value>4</value>
</constructor-arg>
<!-- 验证码 个数最大值 -->
<constructor-arg type="java.lang.Integer" index="1">
<value>4</value>
</constructor-arg>
<!-- 验证码 颜色 -->
<constructor-arg type="java.awt.Color" index="2">
<ref bean="colorGreen"/>
</constructor-arg>
</bean>
<bean id="colorGreen" class="java.awt.Color" >
<constructor-arg index="0"><value>0</value></constructor-arg>
<constructor-arg index="1"><value>0</value></constructor-arg>
<constructor-arg index="2"><value>255</value></constructor-arg>
</bean>
wish can help you best!!!
http://www.iteye.com/topic/156827