Yale CAS 3.1
下载: http://www.ja-sig.org/products/cas/index.html 
1. 修改authenticationViaFormAction以使用自己的Credentials
默认的org.jasig.cas.authentication.principal.UsernamePasswordCredentials只记录用户名和密码,在扩展一些属性如验证码时使用用自己的Credentials类替换
cas-servlet.xml:
<bean id="authenticationViaFormAction" class="org.jasig.cas.web.flow.AuthenticationViaFormAction"
   p:centralAuthenticationService-ref="centralAuthenticationService"
   p:warnCookieGenerator-ref="warnCookieGenerator"
   p:formObjectName="credentials"
   p:formObjectClass="com.nlcd.cas.authentication.principal.EcardCredentials">
      <property name="validator">  
          <bean class="com.nlcd.cas.validation.EcardCredentialsValidator"/>
      </property>
</bean>
EcardCredentialsValidator:
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.nlcd.cas.authentication.principal.EcardCredentials;
public final class EcardCredentialsValidator implements Validator {
     public boolean supports(final Class clazz) {
         return EcardCredentials.class.isAssignableFrom(clazz);
     }
     public void validate(final Object o, final Errors errors) {
         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username",
             "required.username", null);
         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password",
             "required.password", null);
     }
}
EcardCredentials: (加入一个idtype属性)
import org.jasig.cas.authentication.principal.Credentials;
public class EcardCredentials implements Credentials {
/** Unique ID for serialization. */
private static final long serialVersionUID = -7863273946921255486L;
private String idtype;
/** The username. */
     private String username;
     /** The password. */
     private String password;
     public String getIdtype() {
   return idtype;
}
public void setIdtype(String idtype) {
   this.idtype = idtype;
}
/**
      * @return Returns the password.
      */
     public final String getPassword() {
         return this.password;
     }
     /**
      * @param password The password to set.
      */
     public final void setPassword(final String password) {
         this.password = password;
     }
     /**
      * @return Returns the userName.
      */
     public final String getUsername() {
         return this.username;
     }
     /**
      * @param userName The userName to set.
      */
     public final void setUsername(final String userName) {
         this.username = userName;
     }
     public String toString() {
         return this.username;
     }
     public boolean equals(final Object obj) {
         if (obj == null || !obj.getClass().equals(this.getClass())) {
             return false;
         }
         final EcardCredentials c = (EcardCredentials) obj;
         return this.idtype.equals(c.getIdtype()) && this.username.equals(c.getUsername())
             && this.password.equals(c.getPassword());
     }
     public int hashCode() {
         return this.idtype.hashCode() ^ this.username.hashCode() ^ this.password.hashCode();
     }
}
2. 部署自己的authenticationHandlers
deployerConfigContext.xml:
<property name="credentialsToPrincipalResolvers">
    <list>
     <bean
      class="com.nlcd.cas.authentication.principal.EcardCredentialsToPrincipalResolver" />
     <bean
      class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
    </list>
   </property>
   <property name="authenticationHandlers">
    <list>
     <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
      p:httpClient-ref="httpClient" />
     <bean
      class="com.nlcd.cas.authentication.handler.support.EcardAuthenticationHandler" />
    </list>
   </property>
EcardCredentialsToPrincipalResolver:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver;
import org.jasig.cas.authentication.principal.Credentials;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.SimplePrincipal;
public final class EcardCredentialsToPrincipalResolver implements
     CredentialsToPrincipalResolver {
     /** Logging instance. */
     private final Log log = LogFactory.getLog(getClass());
     public Principal resolvePrincipal(final Credentials credentials) {
         final EcardCredentials ecardCredentials = (EcardCredentials) credentials;
         if (log.isDebugEnabled()) {
             log.debug("Creating SimplePrincipal for ["
                 + ecardCredentials.getUsername() + "]");
         }
         return new SimplePrincipal(ecardCredentials.getUsername());
     }
     public boolean supports(final Credentials credentials) {
         return credentials != null
             && EcardCredentials.class.isAssignableFrom(credentials
                 .getClass());
     }
}
EcardAuthenticationHandler:
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.handler.AuthenticationHandler;
import org.jasig.cas.authentication.principal.Credentials;
import org.jasig.cas.util.annotation.NotNull;
import com.nlcd.cas.authentication.principal.EcardCredentials;
public final class EcardAuthenticationHandler implements AuthenticationHandler {
private static final Class<EcardCredentials> DEFAULT_CLASS = EcardCredentials.class;
/** Class that this instance will support. */
@NotNull
private Class<?> classToSupport = DEFAULT_CLASS;
private boolean supportSubClasses = true;
public EcardAuthenticationHandler() {
}
public final boolean authenticate(final Credentials credentials)
    throws AuthenticationException {
   //TODO: your code here
   return true;
}
public final boolean supports(final Credentials credentials) {
   return credentials != null
     && (this.classToSupport.equals(credentials.getClass()) || (this.classToSupport
       .isAssignableFrom(credentials.getClass()))
       && this.supportSubClasses);
}
}
3. 配置Tomcat使用SSL安全认证
生成服务器端密钥:
keytool -genkey -alias nlcdcas -keyalg RSA -keypass changeit -storepass changeit -keystore server.keystore
您的名字与姓氏是什么?
  [192.168.61.56]:  192.168.61.56
您的组织单位名称是什么?
  [nlce]:  nlcd
您的组织名称是什么?
  [Unknown]:  nlcd
您所在的城市或区域名称是什么?
  [Unknown]:  beijing
您所在的州或省份名称是什么?
  [Unknown]:  beijing
该单位的两字母国家代码是什么
  [Unknown]:  cn
CN=192.168.61.56, OU=nlcd, O=nlcd, L=beijing, ST=beijing, C=cn 正确吗?
  [否]:  y
生成服务器端证书:
keytool -export -alias nlcdcas -storepass changeit -file server.cer -keystore server.keystore
导入证书文件到cacerts 文件中:
keytool -import -trustcacerts -alias server -file server.cer -keystore cacerts -storepass changeit
把cacerts文件,拷贝到<JAVA_HOME>\jre\lib\security目录下;server.keystore拷贝到Tomcat安装目录下
修改Tomcat的配置文件server.xml把以下补注释的内容打开
<Connector port="8443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
加入红字部份后的内容如下:
         <Connector port="8443" maxHttpHeaderSize="8192" 
keystorePass="changeit" keystoreFile="/server.keystore"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />