为CAS单点登录服务器增加验证码功能
2009-05-07 16:26
一、 利用CAS实现单点登录
二、 CAS客户端授权JDBC
二、 CAS客户端授权JDBC
添加jcaptcha.jar文件
web.xml:
增加
<servlet-mapping>
<servlet-name>cas</servlet-name>
<url-pattern>/captcha.htm</url-pattern>
</servlet-mapping>
login_webflow.xml:
<action-state id="bindAndValidate">
<action bean="authenticationViaFormAction" />
<transition on="success" to="submit" />
<transition on="error" to="viewLoginForm" />
</action-state>
替换为
<action-state id="bindAndValidate">
<action bean="authenticationViaFormAction" />
<transition on="success" to="captchaValidate" />
<transition on="error" to="viewLoginForm" />
</action-state>
增加
<action-state id="captchaValidate">
<action bean="captchaValidateAction" />
<transition on="success" to="submit" />
<transition on="error" to="viewLoginForm" />
</action-state>
cas_servlet.xml:
增加
<prop key="/captcha.htm">captchaImageCreateController</prop>
<bean id="captchaValidateAction" class="utils.captcha.CaptchaValidateAction"
p:captchaService-ref="jcaptchaService"
p:captchaValidationParameter="j_captcha_response"/>
<bean id="captchaImageCreateController" class="utils.captcha.CaptchaImageCreateController">
<property name="jcaptchaService" ref="jcaptchaService"/>
</bean>
<bean id="fastHashMapCaptchaStore" class="com.octo.captcha.service.captchastore.FastHashMapCaptchaStore" />
<bean id="jcaptchaService" class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService">
<constructor-arg type="com.octo.captcha.service.captchastore.CaptchaStore" index="0">
<ref bean="fastHashMapCaptchaStore"/>
</constructor-arg>
<constructor-arg type="com.octo.captcha.engine.CaptchaEngine" index="1">
<bean class="utils.captcha.JCaptchaEngineEx"/>
</constructor-arg>
<constructor-arg index="2">
<value>180</value>
</constructor-arg>
<constructor-arg index="3">
<value>100000</value>
</constructor-arg>
<constructor-arg index="4">
<value>75000</value>
</constructor-arg>
</bean>
增加java类:
1、
package utils.captcha;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.io.ByteArrayOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class CaptchaImageCreateController implements Controller, InitializingBean {
private ImageCaptchaService jcaptchaService;
public CaptchaImageCreateController(){
}
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
byte captchaChallengeAsJpeg[] = null;
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
String captchaId = request.getSession().getId();
java.awt.image.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", 0L);
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!");
else
return;
}
}
2、
package utils.captcha;
import org.jasig.cas.web.support.WebUtils;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.image.ImageCaptchaService;
public final class CaptchaValidateAction extends AbstractAction {
private ImageCaptchaService jcaptchaService;
private String captchaValidationParameter = "_captcha_parameter";
protected Event doExecute(final RequestContext context) {
String captcha_response = context.getRequestParameters().get(captchaValidationParameter);
boolean valid = false;
if(captcha_response != null){
String id = WebUtils.getHttpServletRequest(context).getSession().getId();
if(id != null){
try {
valid = jcaptchaService.validateResponseForID(id,captcha_response).booleanValue();
} catch (CaptchaServiceException cse) {
}
}
}
if(valid){
return success();
}
return error();
}
public void setCaptchaService(ImageCaptchaService captchaService) {
this.jcaptchaService = captchaService;
}
public void setCaptchaValidationParameter(String captchaValidationParameter) {
this.captchaValidationParameter = captchaValidationParameter;
}
}
3、
package utils.captcha;
import java.awt.Color;
import java.awt.Font;
import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.GradientBackgroundGenerator;
import com.octo.captcha.component.image.color.SingleColorGenerator;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.BaffleTextDecorator;
import com.octo.captcha.component.image.textpaster.textdecorator.LineTextDecorator;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;
public class JCaptchaEngineEx extends ListImageCaptchaEngine {
protected void buildInitialFactories() {
/**
* Set Captcha Word Length Limitation which should not over 6
*/
Integer minAcceptedWordLength = new Integer(4);
Integer maxAcceptedWordLength = new Integer(4);
/**
* Set up Captcha Image Size: Height and Width
*/
Integer imageHeight = new Integer(28);
Integer imageWidth = new Integer(75);
/**
* Set Captcha Font Size between 50 and 55
*/
final Integer minFontSize = new Integer(22);
final Integer maxFontSize = new Integer(22);
/**
* We just generate digit for captcha source char
* Although you can use abcdefg......xyz
*/
WordGenerator wordGenerator = (new RandomWordGenerator("0123456789"));
/**
* cyt and unruledboy proved that backgroup not a factor of Security.
* A captcha attacker won't affaid colorful backgroud, so we just use
* white color, like google and hotmail.
*/
Color bgColor = new Color(255, 255, 255);
BackgroundGenerator backgroundGenerator = new GradientBackgroundGenerator(
imageWidth, imageHeight, bgColor, bgColor);
/**
* font is not helpful for security but it really increase difficultness for attacker
*/
FontGenerator _fontGenerator = new FontGenerator() {
public Font getFont() {
return new Font("Arial", Font.ITALIC, 16);
}
public int getMinFontSize() {
return minFontSize.intValue();
}
public int getMaxFontSize() {
return maxFontSize.intValue();
}
};
/**
* Note that our captcha color is Blue
*/
SingleColorGenerator scg = new SingleColorGenerator(Color.BLACK);
/**
* decorator is very useful pretend captcha attack.
* we use two line text decorators.
*/
LineTextDecorator line_decorator = new LineTextDecorator(new Integer(1), Color.blue);
LineTextDecorator line_decorator2 = new LineTextDecorator(new Integer(1), Color.blue);
TextDecorator[] textdecorators = new TextDecorator[2];
textdecorators[0] = line_decorator;
textdecorators[1] = line_decorator2;
TextPaster _textPaster = new DecoratedRandomTextPaster(minAcceptedWordLength,
maxAcceptedWordLength, scg, new TextDecorator[]{new BaffleTextDecorator(new Integer(0), Color.white)});
/**
* ok, generate the WordToImage Object for logon service to use.
*/
WordToImage wordToImage = new ComposedWordToImage(
_fontGenerator, backgroundGenerator, _textPaster);
addFactory(new GimpyFactory(wordGenerator, wordToImage));
}
}
登录的jsp页面:
增加
<img src="captcha.htm" />
<input type="text" id="j_captcha_response" name="j_captcha_response" />
http://hi.baidu.com/aaspace/blog/item/c87b961803e578bc4bedbc6e.html