Alfresco cas with jasig cas client

cancel
Showing results for 
Search instead for 
Did you mean: 

Alfresco cas with jasig cas client

resplin
Intermediate
0 0 4,385

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