Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
WARNING: THIS CAS SETUP IS NOT OFFICIALLY SUPPORTED BY ALFRESCO.
This wiki page illustrates and example of use of the external authentication subsystem in Alfresco.
Here we use the Jasig Java CAS client.
Install a CAS server
There are several CAS server implementations, see for instance:
SSL certificates
CAS enforces HTTPS on the login form.
You will need to create a SSL certificate.
PEM format
RubyCAS supports the PEM format. You can generate a key, typically using:
openssl req \
-x509 -nodes -days 6365 \
-newkey rsa:1024 -keyout mycert.pem -out mycert.pem
At the CN question:
Common Name (eg, YOUR name) []:
You need to answer with the DNS name of your CAS server.
JKS format
Jasig CAS server supports the JKS keystore format, see oracle JSSERefGuide
keytool -genkey -alias tomcat -keyalg RSA
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: localhost
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]:
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]:
Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
[no]: yes
Enter key password for <tomcat> [mypass]
(RETURN if same as keystore password):
Re-enter new password:
At the question 'What is your first and last name?' you need to respond with the host name of the CAS server (in this test setup 'localhost')
Put that keystore in a folder, e.g.: /etc/keys/keystore1
Note that you can list what is inside your keystore:
keytool -list -v -keystore /etc/keys/keystore1
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: tomcat
Creation date: Mar 26, 2012
Entry type: PrivateKeyEntry
Jasig Dummy CAS server
Jasig CAS server comes with a dummy server where you can authenticate with any username/password where the password is the username. This is handy for testing.
Copy the cas war to Tomcat's webapps/ directory
cp \
/usr/local/cas-server-3.4.11/apache-tomcat-6.0.29/webapps/cas-server-webapp-3.4.11.war \
/opt/alfresco402PgjasigExt/tomcat/webapps
Add the
keystoreFile='/etc/keys/keystore1' keystorePass='mypass'
to the ssl connector in tomcat server.xml
<Connector port='8443' protocol='HTTP/1.1' SSLEnabled='true'
maxThreads='150' scheme='https' secure='true'
keystoreFile='/etc/keys/keystore1' keystorePass='mypass'
clientAuth='false' sslProtocol='TLS' />
Get the Jasig CAS client distribution
Get the file
cas-client-3.2.1-release.zip
from
http://downloads.jasig.org/cas-clients/
Uncompress the archive and install copy the relevant casclient jar files
into your tomcat 'lib' folder:
list='cas-client-core-3.2.1.jar
cas-client-integration-tomcat-common-3.2.1.jar
cas-client-integration-tomcat-v6-3.2.1.jar
commons-codec-1.4.jar
commons-logging-1.1.jar
xmlsec-1.3.0.jar'
for file in $list
do
cp /usr/local/cas-client-3.2.1/modules/$file \
/opt/alfresco402PgjasigExt/tomcat/lib
done
Configure your Alfresco external subsystem
Obviously you will need to put include the external subsystem in your authentication chain:
authentication.chain=external1:external
For a first test you can set:
external.authentication.proxyUserName to a blank value.
Later you probably want to secure your test setup with a SSL client certificate.
Modify the Alfresco web.xml
see
Configuring+the+JA-SIG+CAS+Client+for+Java+in+the+web.xml
Declare a filter
<!-- CAS -->
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://localhost:8443/cas-server-webapp-3.4.11/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://localhost:8443/cas-server-webapp-3.4.11</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<!-- /CAS -->
Apply the filter
You can apply the filters based on URL patterns, e.g:
<!-- CAS -->
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/faces/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/faces/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/faces/*</url-pattern>
</filter-mapping>
<!-- /CAS -->
Modify the Share web.xml
Define the filters
Same web.xml modification as or the alfresco webapp (see above)
Apply the filters
Here is a simple setup. You may want to tune the filters, but filter tuning is not supported by Alfresco Support:
<!-- CAS -->
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- /CAS -->
Modify the share-config-custom.xml
Go to:
./shared/classes/alfresco/web-extension
copy the share-config-custom.xml.sample into share-config-custom.xml and activate SSO (uncommenting the SSO section where the p12 file is mentioned - but not used here)
Test
Accessing Share and Explorer URLs should redirect to the CAS server.
Common Errors
unable to find valid certification path to requested target
2012-07-12 18:10:51,620 ERROR [alfresco.web.site] [http-8080-1] java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:326)
at org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:305)
at org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:50)
at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:207)
at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:169)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
... 31 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 37 more
This can be fixed telling the JVM to trust our keystore:
-Djavax.net.ssl.trustStore=/etc/keys/keystore1 -Djavax.net.ssl.trustStorePassword=mypass
CAS Server could not validate ticket
WARNING: org.jasig.cas.client.validation.TicketValidationException: CAS Server could not validate ticket.
org.jasig.cas.client.validation.TicketValidationException: CAS Server could not validate ticket.
at org.jasig.cas.client.validation.Cas10TicketValidator.parseResponseFromServer(Cas10TicketValidator.java:45)
at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:217)
at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:169)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
2012-07-12 18:24:51,512 ERROR [alfresco.web.site] [http-8080-1] javax.servlet.ServletException: org.jasig.cas.client.validation.TicketValidationException: CAS Server could not validate ticket.
org.jasig.cas.client.validation.TicketValidationException: CAS Server could not validate ticket.
at org.jasig.cas.client.validation.Cas10TicketValidator.parseResponseFromServer(Cas10TicketValidator.java:45)
at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:217)
at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:169)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
This could be caused by a bad filter parameter; e.g. if you put
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://localhost:8443/cas-server-webapp-3.4.11/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</filter>
instead of
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://localhost:8443/cas-server-webapp-3.4.11</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
</filter>
that is you put a URL as casServerUrlPrefix
https://localhost:8443/cas-server-webapp-3.4.11/serviceValidate
instead of the prefix of that URL,
https://localhost:8443/cas-server-webapp-3.4.11
then you will get that kind of error.
Authentication
Single Sign On
CAS