The configurations were tested on the following environment, for others check working path, and available tested release.
See our best practices to install services and keep them up to date.
fedora-release-6-4
cas-server-3.0.5
tomcat5-5.5.17-6jpp.2
ant-1.6.5-2jpp.2 # used to rebuild CAS war
java-1.6.0-sun-compat-1.6.0-1jpp # non default jpackage for SUN
jdk-6-linux-i586.bin # non default SUN package
java-1.6.0-sun-jce-policy-1.6.0-1jpp # unlimited strength for certificate keys
jpackage-utils-1.7.3-1jpp.2.fc6 # used for SUN java install
rpmdevtools-5.3-1.fc6 # used for SUN java install
selinux-policy-targeted-2.4.6-1.fc6
fedora-release-5-5
cas-server-3.0.5
tomcat5-5.5.15-1jpp_6fc
ant-1.6.5-1jpp_7fc # used to rebuild CAS war
java-1.5.0-sun-1.5.0.09-1jpp # non default jpackage for SUN
jdk-1_5_0_09-linux-i586.bin # non default SUN package
jce_policy-1_5_0.zip # unlimited strength for certificate keys
jpackage-utils-1.6.6-1jpp_2rh # used for SUN java install
rpmdevtools-5.2-1.fc5 # used for SUN java install
selinux-policy-targeted-2.3.7-2.fc5
| CAS with x509 certificates |
Configuring CAS to allow authentication with X509 certificates, allows you to use certificates to authenticate with potentially all CAS enabled services. Of course each of these services needs to be properly configured to use your CAS server, unless you participate in an Identity federation using other's CAS servers accepting certificates.
When you want to configure a CAS server, these are the basic steps:
- Check that you have a JKS (Java Key Store) for the CAS service
- Customize CAS webflow in login-webflow.xml
- Make certificate authentication available in cas-servlet.xml
- Configure how to handle client certificates in deployerConfigContext.xml
- Configure tomcat SSL ports in server.xml casSSLports
- Check tomcat login configuration for CAS casLogin
- Start tomcat or check log if already started
Return to top of page topCAS
If you got your keyset in PEM format mostly used in Linux environment, you need to use Linux openssl to first convert them to a PKCS12 store, then go to PKCS12-JKS conversion pkcs12JKS.
Example
Where MyName.pem is your user certificate file
Where MyName.key is your private key file
Where MyNameCA.pem is your Certification authority certificates file
Create a bundle with MyNameCA.pem and MyName.pem
Where MyName.bundle.pem is the bundle file name
[root@example-host tls]# cat MyNameCA.pem MyName.pem > MyName.bundle.pem
Create a PKCS12 key set with MyName.bundle.pem and MyName.key
Where MyName.p12 is the keyset file name
Where My_short_Name is an arbitrary display name in your keyset
[root@example-host tls]# openssl pkcs12 -export -in MyName.bundle.pem -inkey MyName.key -out MyName.p12 -name "My_short_Name"
 | Warning
In case of chained CA certificates (Root CA and Sub CA), in regular pem format, the SubCA is first and the RootCA second. PKCS12 needs them in the reverse order before the client certificate. Therefore the bundle file must be constructed manually with individual certificates. Then edit the bundle and check for correct new line / line break between certificates blocks. |
Return to top of page topCAS
If you have your host's certificate in PKCS12 format (with .p12 .pfx extension for MS Windows), although Tomcat MAY use PKCS12 format (with keystoreType="PKCS12" in the SSL connector element), it is recommended to export all the components to JKS format (JAVA standard) for coherence with others Java applications.
To convert the PKCS12 bundle virtual-host.p12 to JKS virtual-host.jks
Provided org.mortbay.jetty.jar is installed in /opt
[root@example-host jks]# java -classpath /opt/org.mortbay.jetty.jar org.mortbay.util.PKCS12Import virtual-host.p12 virtual-host.jks
\>Enter input keystore passphrase: mypasswd
\>Enter output keystore passphrase: mypasswd
\>Alias 0: virtual-host
\>Adding key for alias virtual-host
You can get org.mortbay.jetty.jar here
Return to top of page topCAS
Customize CAS webflow in login-webflow.xml
You need to update the following file:
/opt/cas-server-3.0.5/localPlugins/target/webapp/WEB-INF/login-webflow.xml
Pay attention to startAuthenticate values and element action bean="x509Check"
<action-state id="gatewayRequestCheck">
<action bean="gatewayRequestCheckAction" />
<transition on="gateway" to="redirect" />
<transition on="authenticationRequired" to="startAuthenticate" />
</action-state>
<action-state id="hasServiceCheck">
<action bean="hasServiceCheckAction" />
<transition on="authenticatedButNoService" to="viewGenericLoginSuccess"/>
<transition on="hasService" to="renewRequestCheck" />
</action-state>
<action-state id="renewRequestCheck">
<action bean="renewRequestCheckAction" />
<transition on="authenticationRequired" to="startAuthenticate" />
<transition on="generateServiceTicket" to="generateServiceTicket" />
</action-state>
<action-state id="startAuthenticate">
<action bean="x509Check" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="error" to="viewLoginForm" />
</action-state>
<view-state id="viewLoginForm" view="casLoginView">
<transition on="submit" to="bindAndValidate" />
</view-state>
<action-state id="bindAndValidate">
<action bean="authenticationViaFormAction" />
<transition on="success" to="submit" />
<transition on="error" to="viewLoginForm" />
</action-state>
<action-state id="generateServiceTicket">
<action bean="generateServiceTicketAction" />
<transition on="success" to ="warn" />
<transition on="error" to="startAuthenticate" />
<transition on="gateway" to="redirect" />
</action-state>
Return to top of page topCAS
Make certificate authentication available in cas-servlet.xml
You need to update the following file:
/opt/cas-server-3.0.5/localPlugins/target/webapp/WEB-INF/cas-servlet.xml
<bean
id="x509Check"
parent="abstractCasLoginAction"
class="org.jasig.cas.adaptors.x509.web.flow.X509CertificateCredentialsNonInteractiveAction" />
Return to top of page topCAS
Configure how to handle client certificates in deployerConfigContext.xml
You need to update the following file:
/opt/cas-server-3.0.5/localPlugins/target/webapp/WEB-INF/deployerConfigContext.xml
with a CredentialsToPrincipalResolver feature. That is: a way to extract information from authenticated client certificate and pass it to the "CAS enabled application". For this you MUST understand "osi names" embedded in certificates (check osiNames and Filling DN tabs topCAS).
CAS provides you with several CredentialsToPrincipalResolver, each allowing a given mapping between certificate's subject and an authentication identity. Note that From CAS v3.0.6 you can combine any X.509 credentialsToPrincipalResolvers with an LDAP resolver to map a certificate to a user in your LDAP repository (unfortunately it requires a clear text password to access LDAP).
Here is an example where:
- The "CredentialsToPrincipalResolver" is org.jasig.cas.adaptors.x509.authentication.principal.X509CertificateCredentialsToIdentifierPrincipalResolver it maps a component of the distinguished name (certificate subject) to an authentication identity
- The extracted component will be the CN (common name)
- The trust CA issuer subject is DC=org,DC=openosi,OU=pki,CN=openosiCA1-DC
<beans>
<bean id="authenticationManager"
class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<bean
class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />
<bean
class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" />
<bean
class="org.jasig.cas.adaptors.x509.authentication.principal.X509CertificateCredentialsToIdentifierPrincipalResolver" >
<property name="identifier"
value="$CN" />
</bean>
</list>
</property>
<property name="authenticationHandlers">
<list>
<bean
class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" />
<bean
class="org.jasig.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler">
<property name="trustedIssuer"
value="DC=org, DC=openosi, OU=pki, CN=openosiCA1-DC" />
</bean>
</list>
</property>
</bean>
</beans>
Return to top of page topCAS
You need to configure the following ports:
- One port requiring client certificate for authentication
- One port that don't requires client certificate for others actions
Example with client certificate authentication on port 8443
Where:
Your java key store is cas.jks with password MyPassword
Your trusted CA certificates file is cacerts.trust with password caPassword
Where clientAuth="true" requires valid certificate
<Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystore="/usr/local/tomcat/conf/cas.jks"
keystorePass="MyPassword" URIEncoding="UTF-8"
truststoreFile="/usr/local/tomcat/conf/cacerts.trust"
truststorePass="caPassword"/>
Example without client certificate request on port 8444
Where:
Your java key store is cas.jks with password MyPassword
Your trusted CA certificates file is default cacerts with password changeit
Where clientAuth="false" doesn't requires client certificate presentation
<Connector port="8444" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystore="/usr/local/tomcat/conf/cas.jks"
keystorePass="MyPassword" URIEncoding="UTF-8"
truststoreFile="/usr/lib/jvm/jre/lib/security/cacerts"
truststorePass="changeit"/>
Return to top of page topCAS
Check tomcat login configuration for CAS
Check if you already have a common log4j.properties in /usr/local/tomcat/common/classes. If yes, remove /opt/cas-server-3.0.5/webapp/WEB-INF/classes/logger.properties
Update /usr/local/tomcat/common/classes/log4j.properties
### cas-server ###
log4j.logger.org.jasig.cas=INFO, CAS_APPENDER
#log4j.logger.org.jasig.cas.authentication=DEBUG
#log4j.logger.org.jasig.cas.web.flow.TicketGrantingTicketCheckAction=DEBUG
#log4j.logger.org.jasig.cas.services=DEBUG
#log4j.logger.org.jasig.cas.services.DefaultServiceRegistry=DEBUG
#log4j.logger.org.jasig.cas.ticket=DEBUG
#log4j.logger.org.jasig.cas.web.flow.X509CertificateCredentialsNonInteractiveAct
ion=DEBUG
#log4j.logger.org.jasig.cas.adaptors.x509=DEBUG
#log4j.logger.org.jasig.cas.adaptors.ldap.authentication.principal.CredentialsTo
#LDAPAttributePrincipalResolver=DEBUG
#log4j.logger.org.jasig.cas.adaptors.ldap=DEBUG
#log4j.logger.org.jasig.cas.adaptors.radius=DEBUG
log4j.logger.org.esupportail.cas.server.GenericHandler=INFO, CAS_APPENDER
log4j.logger.org.springframework=WARN, CAS_APPENDER
#log4j.logger.org.springframework.web.servlet.view=DEBUG
#log4j.logger.org.springframework.web.servlet.i18n=DEBUG
log4j.logger.org.quartz=INFO, CAS_APPENDER
# Configuration for a rolling log file ("cas.log").
log4j.appender.CAS_APPENDER=org.apache.log4j.DailyRollingFileAppender
log4j.appender.CAS_APPENDER.DatePattern='.'yyyy-MM-dd
log4j.appender.CAS_APPENDER.File=${catalina.home}/logs/cas.log
log4j.appender.CAS_APPENDER.Encoding=UTF-8
log4j.appender.CAS_APPENDER.layout=org.apache.log4j.PatternLayout
log4j.appender.CAS_APPENDER.layout.ConversionPattern=%5p [%t] %c{2}.[%x] %d{MMM/
dd HH:mm:ss} - %m%n
Update /opt/cas-server-3.0.5/webapp/WEB-INF/web.xml
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jExposeWebAppRoot</param-name>
<param-value>false</param-value>
</context-param>
OSI stands for "Open Standards for Interconnection" from ISO / ITU
an OSI name is called a "Distinguished name" which is used in all OSI related technologies such as
- Certificates (X509)
- LDAP directories including Microsoft Active directory (X500)
- Military and aeronautical messaging systems (X400)
A "Distinguished name" (DN) is a collection of one or more of the following components
- CN Common name
- OU Organisation Unit
- O Organization
- C Country
- and many others like "givenname","sn surname","l location" ......
Example DN
DN: cn=My_full_name,ou=Related_Organisation_Unit,ou=other_related_unit,o=Company_name,c=country
or with the alternate DC scheme mostly used in directories.
DN:cn=My_full_name,ou=Related_Organisation_Unit,ou=other_related_unit,dc=example,c=com
 | Useful Information
If you want to participate in the openLDAP referral service (ldap://root.openldap.org) you MUST use the DC scheme and set appropriate SRV records in your DNS. |
Common meanings of OU are as follows:
- OU=Hosts
- OU=People # users
- OU=Services # Daemons
openOSI also uses in its naming scheme:
- OU=VirtualHosts
- OU=VirtualPeople # nicknames
- OU=PKI # Certification authorities
In principle you are free to use what you want as DN components value, unless you request a certification authority to certify these values. That is unless you intend a public use of these names to participate in an Internet of trust (similarly to the dns - Domain name system).
You MUST use a "Distinguished name" to generate a certificate request.
For additional information check the various OSI X500 and RFC
 | Useful Information
There could be links between DNS and OSI naming scheme, especially when domain components are used for distinguished names. Some people stores DNS DB in an LDAP directory (like Microsoft optionally). Most people don't in order to keep loosely coupling between DNS and Directories. There is an interesting use of LDAP directories for certificates when storing these certificates and their revocation list (CRL) in the directories. Therefore you MAY imagine a scheme that facilitate directory searching for your certificate retrieval. That is unless you use a third part directory like openOSI (directory.opensosi.org). openOSI practice is to store your certificate in virtual OU unit according the openOSI naming scheme without relying on the distinguished name of the certificate. |