Hi Alex,
Thanks for this integration. Could you submit this in the CAS User Manual ?
To keep a better trace of your work ?
I've just look at this integration without making my own practical test. But
your count variable is in the flowScope this mean, it is linked to the user
session. So an attacker who is removing it's user session between to
tentative won't have to defeat your captcha, right ?
Or am I missing something ?
Regards,
Arnaud Lesueur
On Tue, Jun 17, 2008 at 2:41 PM, Axel Mendoza Pupo <[EMAIL PROTECTED]>
wrote:
> to integrate JCAPTCHA with CAS some changes has need
>
> In the login-webflow.xml:
>
> 1- Replace the action state bindAndValidate for this
>
> <action-state id="bindAndValidate">
> <action bean="authenticationViaFormAction" />
> <transition on="success" to="captchaCheck" />
> <transition on="error" to="errorCount" />
> </action-state>
>
> 2- Replace the action state submit for this
>
> <action-state id="submit">
> <action bean="authenticationViaFormAction" method="submit" />
> <transition on="warn" to="warn" />
> <transition on="success" to="sendTicketGrantingTicket" />
> <transition on="error" to="errorCount" />
> </action-state>
>
> 3-Add the new action states
>
> <decision-state id="captchaCheck">
> <if test="${flowScope.count != null && flowScope.count >= 3}"
> then="captchaValidate" else="submit"/>
> </decision-state>
>
> <action-state id="captchaValidate">
> <action bean="captchaValidateAction" />
> <transition on="success" to="submit" />
> <transition on="error" to="errorCount" />
> </action-state>
>
> <action-state id="errorCount">
> <action bean="captchaErrorCountAction" />
> <transition on="success" to="viewLoginForm" />
> </action-state>
>
> //*******************************************************
> the code for the action bean CaptchaErrorCountAction
>
> 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;
>
> public final class CaptchaErrorCountAction extends AbstractAction {
>
> protected Event doExecute(final RequestContext context) {
> int count;
> try {
> count = (Integer)context.getFlowScope().get("count");
> } catch (Exception e) {
> count=0;
> }
>
> count++;
>
> context.getFlowScope().put("count", count);
>
> return success();
> }
>
> }
>
> //*******************************************************
> the code for the action bean captchaValidateAction
>
> 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,
> response).booleanValue();
> } catch (CaptchaServiceException cse) {
> }
> }
> }
>
> if(valid){
> return success();
> }
>
> return error();
> }
>
> public void setCaptchaService(JCaptchaServiceProxy captchaService) {
> this.captchaService = captchaService;
> }
>
> public void setCaptchaValidationParameter(String
> captchaValidationParameter) {
> this.captchaValidationParameter = captchaValidationParameter;
> }
> }
> //*******************************************************
>
> to generate the captcha image you must add a new controller to send the
> image in response to your image url
>
> //*******************************************************
> the code for the controller that process the image url
>
> 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
> {
> 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;
> }
> private ImageCaptchaService jcaptchaService;
> }
> //*******************************************************
>
> You should configure this controller in cas-servlet.xml and map to the url
> that the controller will process add the following to the handlerMappingC
> bean in the property mappings
> <prop
> key="/captcha.htm">
> captchaImageCreateController
> </prop>
>
> /captcha.htm or whatever url that you want to set shoul be map in the
> web.xml by add the following
> <servlet-mapping>
> <servlet-name>cas</servlet-name>
> <url-pattern>/captcha.htm</url-pattern>
> </servlet-mapping>
>
> The last step is the use of this url in our authentication page by add the
> following JSP code
> <c:if test="${not empty count && count >= 3}" >
> <img src="captcha.htm" >
> <input name="j_captcha_response" type="text">
> </c:if>
>
> //*******************************************************
> the configuration of the beans described here
>
> <bean id="captchaErrorCountAction"
> class="your.path.CaptchaErrorCountAction"/>
>
> <bean id="captchaValidateAction" class="your.path.CaptchaValidateAction"
> p:captchaService-ref="captchaService"
> p:captchaValidationParameter="j_captcha_response"/>
>
> <bean id="captchaImageCreateController"
> class="your.path.CaptchaImageCreateController">
> <property name="jcaptchaService" ref="jcaptchaService" />
> </bean>
>
> the configuration of the bean jcaptchaService is bussiness of the
> developer, the following is an example
> <bean id="jcaptchaService"
> class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService"/>
>
>
>
> _______________________________________________
> Yale CAS mailing list
> [email protected]
> http://tp.its.yale.edu/mailman/listinfo/cas
>
>
--
Arnaud Lesueur
LinkedIn: http://www.linkedin.com/in/lesueur
_______________________________________________
Yale CAS mailing list
[email protected]
http://tp.its.yale.edu/mailman/listinfo/cas