JCaptcha

CAS4 includes basic support for JCaptcha. In its simplest form, CAPTCHA helps determine whether the subject using your application is a human or not. For a more precise and long-winded definition, please see the Wikipedia article.

How is CAS using CAPTCHA?

Prompting your users on every attempt to authenticate would be an unfair burden (not to mention, REALLY ANNOYING). Thus, CAS does not present the CAPTCHA on every request to collect credentials. CAS only presents a CAPTCHA when a specific criteria is met. For example, you may wish to only display CAPTCHA if there are 7 failed authentications in less than one minute.

Trying it Out

The default CAS demonstration WAR file has CAPTCHA enabled, with very relaxed rules (two failed authentication attempts in 60 seconds), so it should be fairly easy for you to trigger it.

Configuring CAPTCHA in YOUR application

This section includes detailed instructions on including CAPTCHA from within your application.

Adding CAPTCHA Support to your POM file

You'll need to add basic CAPTCHA support to your POM, by adding the following dependency:

<dependency>
     <groupId>org.jasig.cas</groupId>
     <artifactId>cas-server-integration-jcaptcha</artifactId>
     <version>${project.version}</version>
</dependency>

You'll also need to add a storage mechanism for JCaptcha, based on your overall storage requirements. If you're only using one CAS server, for example, you would use the in-memory version:

<dependency>
   <groupId>org.jasig.cas</groupId>
   <artifactId>cas-server-integration-jcaptcha-inmemory</artifactId>
   <version>${project.version}</version>
</dependency>

Please note, in both cases, the "project.version" variable refers to the current version of CAS that you are using (i.e. 4.0.0).

Adding CAPTCHA Support to your Web Flow

Adding CAPTCHA support to your web flow allows the CAPTCHA to be displayed on the login form.

First, add the following to your binder (of the promptForCredentials action):

<binding property="captchaResponse" required="false" />

It should now look something like this:

<binder>
     <binding property="username" required="true" />
     <binding property="password" required="true" />
     <binding property="captchaResponse" required="false" />
</binder>

Next, add the following on-entry items:

<evaluate expression="captchaStatusStorage.getCaptchaStatus(requestScope.loginResponse.attributes['captchaId'] eq null ? '' : requestScope.loginResponse.attributes['captchaId'])" result="viewScope.captchaStatus" result-type="org.jasig.cas.server.authentication.CaptchaStatus" />

It should now look something like this:

<on-entry>
     <evaluate expression="captchaStatusStorage.getCaptchaStatus(requestScope.loginResponse.attributes['captchaId'] eq null ? '' : requestScope.loginResponse.attributes['captchaId'])" result="viewScope.captchaStatus" result-type="org.jasig.cas.server.authentication.CaptchaStatus" />
     <evaluate expression="loginRequest.credentials.clear()" />
     <set name="viewScope.loginResponse" value="requestScope.loginResponse" />
</on-entry>

Finally, replace the "credentials" variable line with the following:

<var name="credentials" class="org.jasig.cas.server.authentication.CaptchaUsernamePasswordCredentialImpl" />

Adding CAPTCHA Support to your JSP Page

To have a CAPTCHA box show up on your JSP page, you would need to add the following snippit of code (possibly formatted more nicely)

<c:if test="${captchaStatus != null and captchaStatus.inViolation}">
   <img src="captchaService?id=${loginResponse.attributes['captchaId']}" alt="CAPTCHA Image" />
   <input type="text" name="captchaResponse" value="" />
</c:if>

This page checks the CaptchaStatus object to determine if it should display the CAPTCHA image or not and the associated input field.

What Gets Configured Automatically

As part of the inclusion of the integration jars with your CAS web application, there are a few items that are configured automatically:
#two plugins (CaptchaAuthenticationResponsePluginImpl and CaptchaPreAuthenticationPluginImpl) that detects if there was a failed authentication and updates the CaptchaStatus, and also checks the value.

  1. a CaptchaIdGenerator that bases it on a combined username and ip address.
  2. a controller (JCaptchaController) that is automatically registered at /jcaptchaService to generate images.

Spring Configuration

Create a "jcaptcha-configuration.xml" in the WEB-INF/spring directory of your web application.

Add the following file:

jcaptcha-configuration.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (C) 2009 Jasig, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

            http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <bean class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService" id="imageCaptchaService" />

    <bean class="org.jasig.cas.server.authentication.DefaultCaptchaStatusImplFactory" id="captchaStatusFactory"
          p:numberOfFailures="2"
          p:numberOfMilliseconds="60000" />

    <bean class="org.jasig.cas.server.authentication.InMemoryCaptchaStatusStorageImpl" id="captchaStatusStorage" />
</beans>

The above code creates the CAPTCHA Image Services, configures the in-memory storage implementation, and configures a CaptchaStatusFactory that will generates CaptchaStatuses that will cause a violation after 2 failures in 60 seconds. You'll want to customize that to meet your needs. If you use a different storage mechanism, you'll want to replace the InMemory one.

Customizing the CAPTCHA Image

The default image created may not be the one you'd like to use. The JCaptcha web site provides details on using different image services and engines: