Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
The following is a recipe for installing the Alfresco Explorer and Share web applications on a Red Hat Enterprise Linux 5.2 server that uses a Central Authentication Service (CAS) server as a Single Sign-On (SSO) solution. The mechanisms used are fairly generic, and thus may work with other SSO systems too. This recipe makes use of the new External authentication subsystem, and thus will only work with a build of the very latest code from HEAD or the upcoming Alfresco v3.2 Enterprise release.
NOTE: CAS 3.3.5 is the only version that has been confirmed to work with Alfresco with the configuration given below. CAS 3.4.3.1 requires changes to this configuration. The Alfresco end point and filter should be fine if the same request headers are generated.
We will require an Apache server with mod_ssl installed, as well as the packages required to compile and install other apache modules. We also require MySQL to support Alfresco. So ensure the following packages are installed
Please also ensure that Red Hat's tomcat packages are not installed, as CAS and Alfresco will require their own 'virgin' Tomcat 6 installation later.
Download the Sun JDK 1.6 rpm.bin from http://java.sun.com and run it to install Sun JDK 1.6
Download and extract the following under /opt
Put this line in /opt/apache-tomcat-6.0.20/conf/catalina.properties to enable the shared classloader, required by Alfresco
shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar
Add in the extension classpath directories that will be required by Alfresco
mkdir -p /opt/apache-tomcat-6.0.20/shared/classes/alfresco/extension
mkdir -p /opt/apache-tomcat-6.0.20/shared/classes/alfresco/web-extension
We are going to be relying on the Apache HTTP Server for authentication rather than tomcat, so in /opt/apache-tomcat-6.0.20/conf/server.xml, disable Tomcat authentication on the AJP 1.3 connector by setting tomcatAuthentication='false' like so:
<Connector port='8009' protocol='AJP/1.3' redirectPort='8443' tomcatAuthentication='false'/>
Now edit /root/.bashrc to set up your environment appropriately
export JAVA_OPTS='-Xmx1024M -XX:MaxPermSize=128M -Dcom.sun.management.jmxremote -Dalfresco.home=.'
export JAVA_HOME=/usr/java/latest
export MVN_HOME=/opt/apache-maven-2.2.1
export ANT_HOME=/opt/apache-ant-1.6.5
export CATALINA_HOME=/opt/apache-tomcat-6.0.20
export TOMCAT_HOME=$CATALINA_HOME
export APP_TOMCAT_HOME=$CATALINA_HOME
# Set the following variable, even if the directory doesn't exist
# This is so that we can use the incremental-tomcat target in the alfresco build
export VIRTUAL_TOMCAT_HOME=/opt/apache-tomcat-5.5.28
export PATH=$JAVA_HOME/bin:$CATALINA_HOME/bin:$MVN_HOME/bin:$ANT_HOME/bin:$PATH
Open the file /etc/pki/tls/openssl.cnf (or /etc/ssl/openssl.cnf on Ubuntu) in a text editor (such as gedit). Edit the '[req_distinguished_name]' section so that it has defaults appropriate for your organization. For example:
countryName_default = GB
stateOrProvinceName_default = Berkshire
localityName_default = Maidenhead
0.organizationName_default = Alfresco Software Inc.
Now we will create the self-signed certificate for our Certificate Authority (CA). Use the exact paths listed here, as they are already referenced in openssl.cnf. (For Ubuntu replace /etc/pki/CA/... with /etc/ssl/demoCA/... Or check the openssl.cnf file for the dir option.) When asked for the certificate subject, enter the name for your authority, such as 'Dave's Certificate Authority'.
mkdir /etc/pki/CA/{certs,crl,newcerts,private}
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
cd /etc/pki/CA/
(umask 077; openssl genrsa -out private/cakey.pem -des3 2048)
openssl req -new -x509 -key private/cakey.pem -days 365 > cacert.pem
Now let's ensure that certificates issued by our CA are trusted by the Apache HTTP Server. We need to create a symbolic link to the certificate using a computed hash to add it to the chain of trust. There's a little bit of extra configuration we make later to complete this.
cp cacert.pem /etc/pki/tls/certs/
cd /etc/pki/tls/certs/
ln -s cacert.pem `openssl x509 -hash -noout -in cacert.pem`.0
While we're here, let's replace the HTTP server's test certificate with a 'real' one issued by our CA. The advantages of it being issued by the same CA are that we'll have fewer certificates to add to Alfresco Share's trust store later on! The certificate subject must match the external DNS name of your server. We use the -nodes option to avoid having to enter a key password every time we start apache!
cd /etc/pki/tls/certs
openssl req -nodes -new -out localhost.csr -keyout ../private/localhost.key
openssl ca -out localhost.crt -infiles localhost.csr
rm localhost.csr
Now let's issue a certificate that we will use to securely identify the Alfresco Share application to the Alfresco repository application. This time we protect the private key with a password and also export the key and its certificate chain to a password protected PKCS12 keystore alfresco-system.p12 in the Tomcat classpath so that it may be used by the Share application. Use the same password for both the key and the keystore. For the subject name, use alfresco-system. We will later configure Alfresco to trust that this subject is the Share application, by using the external authentication handler in the authentication chain. By default Alfresco trusts the CN of alfresco-system as a proxy user (essentially share is proxying authentication to alfresco by using a certificate).
(Note that the trusted user can be anything you want, by defining it in the external.authentication.proxyUserName option of alfresco-global.properties file.)
cd /etc/pki/tls/certs
openssl req -new -out alfresco-system.csr -keyout ../private/alfresco-system.key
openssl ca -out alfresco-system.crt -infiles alfresco-system.csr
rm alfresco-system.csr
openssl pkcs12 -export -out /opt/apache-tomcat-6.0.20/shared/classes/alfresco/web-extension/alfresco-system.p12 -in alfresco-system.crt -inkey ../private/alfresco-system.key -chain
The -chain option looks for the cacert.pem file in the default location (defined in openssl.conf). If this does not get picked up properly, you may get 'Error unable to get local issuer certificate getting chain.'. To get around this you can explicitly set the cacert to use, by using the -certfile option instead of -chain (so -certfile /etc/ssl/certs/cacert.pem, for example).
We are going to use the method described here to build our own pre-configured CAS Server using Maven that integrates with our Enterprise's authentication systems.
Execute the following commands to set yourself up an appropriate directory structure in which to work.
cd /root
mkdir -p custom-cas-server/src/main/webapp/WEB-INF/classes
cd custom-cas-server
First, let's create the Maven Project Object Model (POM) for our customized server. Create a file pom.xml that pulls in the required CAS Server dependencies. We are using CAS 3.3.5, as 3.4 introduced some incompatibilities (namely switching from Spring Webflow 1 to Spring Webflow 2) that prevent the solution described in this page working with the latter. Note that we include LDAP and X509 certificate support:
<project xmlns='http://maven.apache.org/POM/4.0.0'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'>
<modelVersion>4.0.0</modelVersion>
<groupId>org.alfresco.cas</groupId>
<artifactId>alfresco-cas</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Alfresco CAS webapp</name>
<organization>
<name>Alfresco</name>
<url>http://www.alfresco.com</url>
</organization>
<description>Alfresco's configuration of the JA-SIG CAS server.</description>
<dependencies>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-webapp</artifactId>
<version>3.3.5</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-core</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-support-ldap</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-support-x509</artifactId>
<version>3.3.5</version>
</dependency>
</dependencies>
<build>
<finalName>cas</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>RELEASE</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jasig-repository</id>
<name>JA-SIG Maven2 Repository</name>
<url>http://developer.ja-sig.org/maven2</url>
</repository>
</repositories>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changelog-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</project>
Now, we just need to add in the files we wish to customize. Create the main Spring configuration file in src/main/webapp/WEB-INF/deployerConfigContext.xml
A few points to note
<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'
xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd'>
<bean id='contextSource' class='org.springframework.ldap.core.support.LdapContextSource'>
<property name='pooled' value='true' />
<property name='urls'>
<list>
<value>ldap://ldap.host.com:389/</value>
</list>
</property>
<property name='userDn' value='alfresco@domain' />
<property name='password' value='secret' />
<property name='baseEnvironmentProperties'>
<map>
<entry>
<key>
<value>java.naming.security.authentication</value>
</key>
<value>simple</value>
</entry>
</map>
</property>
</bean>
<bean id='authenticationManager' class='org.jasig.cas.authentication.AuthenticationManagerImpl'>
<property name='credentialsToPrincipalResolvers'>
<list>
<bean
class='org.jasig.cas.adaptors.x509.authentication.principal.X509CertificateCredentialsToIdentifierPrincipalResolver'>
<property name='identifier' value='$CN' />
</bean>
<bean class='org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver' />
<bean class='org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver' />
</list>
</property>
<property name='authenticationHandlers'>
<list>
<bean class='org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler'>
<property name='httpClient' ref='httpClient' />
</bean>
<bean class='org.jasig.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler'>
<property name='trustedIssuerDnPattern' value='^.*CN=Dave's Certificate Authority, O=Alfresco Software Inc\., L=Maidenhead, ST=Berkshire, C=GB$' />
</bean>
<bean class='org.jasig.cas.adaptors.ldap.FastBindLdapAuthenticationHandler'>
<property name='filter' value='%u@domain' />
<property name='contextSource' ref='contextSource' />
</bean>
</list>
</property>
</bean>
<bean id='userDetailsService' class='org.springframework.security.userdetails.memory.InMemoryDaoImpl'>
<property name='userMap'>
<value>
</value>
</property>
</bean>
<bean id='attributeRepository' class='org.jasig.services.persondir.support.StubPersonAttributeDao'>
<property name='backingMap'>
<map>
<entry key='uid' value='uid' />
<entry key='eduPersonAffiliation' value='eduPersonAffiliation' />
<entry key='groupMembership' value='groupMembership' />
</map>
</property>
</bean>
<bean id='serviceRegistryDao' class='org.jasig.cas.services.InMemoryServiceRegistryDaoImpl' />
<bean id='x509Check' p:centralAuthenticationService-ref='centralAuthenticationService'
class='org.jasig.cas.adaptors.x509.web.flow.X509CertificateCredentialsNonInteractiveAction'>
<property name='centralAuthenticationService' ref='centralAuthenticationService' />
</bean>
</beans>
Now, add your logging configuration to src/main/webapp/WEB-INF/classes/log4j.properties
Note we have added one line to the standard file in order to get debugging information from the X509CredentialsAuthenticationHandler
log4j.logger.org.jasig.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler=DEBUG
For maximum debug information, you may even go as far as changing this line
log4j.logger.org.jasig=INFO
to
log4j.logger.org.jasig=DEBUG
The full file is below
# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=ERROR, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] -
Finally, create a file src/main/webapp/WEB-INF/login-webflow.xml with the customizations described here to ensure auto-redirect through the login screen with the client certificate we exported to alfresco-system.p12. It should be fine to copy the version below without making any edits.
<flow xmlns='http://www.springframework.org/schema/webflow'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd'>
<start-state idref='initialFlowSetup'/>
<action-state id='initialFlowSetup'>
<action bean='initialFlowSetupAction' />
<transition on='success' to='ticketGrantingTicketExistsCheck' />
</action-state>
<decision-state id='ticketGrantingTicketExistsCheck'>
<if test='${flowScope.ticketGrantingTicketId != null}' then='hasServiceCheck' else='gatewayRequestCheck' />
</decision-state>
<decision-state id='gatewayRequestCheck'>
<if test='${externalContext.requestParameterMap['gateway'] != && externalContext.requestParameterMap['gateway'] != null && flowScope.service != null}' then='redirect' else='startAuthenticate' />
</decision-state>
<decision-state id='hasServiceCheck'>
<if test='${flowScope.service != null}' then='renewRequestCheck' else='viewGenericLoginSuccess' />
</decision-state>
<decision-state id='renewRequestCheck'>
<if test='${externalContext.requestParameterMap['renew'] != && externalContext.requestParameterMap['renew'] != null}' then='startAuthenticate' else='generateServiceTicket' />
</decision-state>
<decision-state id='warn'>
<if test='${flowScope.warnCookieValue}' then='showWarningView' else='redirect' />
</decision-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'>
<render-actions>
<action bean='authenticationViaFormAction' method='setupForm'/>
<action bean='authenticationViaFormAction' method='referenceData'/>
</render-actions>
<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='submit'>
<action bean='authenticationViaFormAction' method='submit' />
<transition on='warn' to='warn' />
<transition on='success' to='sendTicketGrantingTicket' />
<transition on='error' to='viewLoginForm' />
</action-state>
<action-state id='sendTicketGrantingTicket'>
<action bean='sendTicketGrantingTicketAction' />
<transition on='success' to='serviceCheck' />
</action-state>
<decision-state id='serviceCheck'>
<if test='${flowScope.service != null}' then='generateServiceTicket' else='viewGenericLoginSuccess' />
</decision-state>
<action-state id='generateServiceTicket'>
<action bean='generateServiceTicketAction' />
<transition on='success' to ='warn' />
<transition on='error' to='viewLoginForm' />
<transition on='gateway' to='redirect' />
</action-state>
<end-state id='viewGenericLoginSuccess' view='casLoginGenericSuccessView' />
<end-state id='showWarningView' view='casLoginConfirmView' />
<end-state id='redirect' view='bean:dynamicRedirectViewSelector' />
<end-state id='viewServiceErrorView' view='viewServiceErrorView' />
<end-state id='viewServiceSsoErrorView' view='viewServiceSsoErrorView' />
<global-transitions>
<transition to='viewServiceErrorView' on-exception='org.springframework.webflow.execution.repository.NoSuchFlowExecutionException' />
<transition to='viewServiceSsoErrorView' on-exception='org.jasig.cas.services.UnauthorizedSsoServiceException' />
<transition to='viewServiceErrorView' on-exception='org.jasig.cas.services.UnauthorizedServiceException' />
</global-transitions>
</flow>
We're now ready to build our configured version of the CAS war file and plug it into Tomcat:
cd /root/custom-cas-server
mvn -Dmaven.test.skip=true package install
cp target/cas.war /opt/apache-tomcat-6.0.20/webapps/
Ensure Apache HTTP Server is not running
/etc/init.d/httpd stop
Download and extract the following under /root
Now build and install with the following commands
cd /root/tomcat-connectors-1.2.28-src/native
./configure --with-apxs=/usr/sbin/apxs; make; make install
mkdir /opt/apache-tomcat-6.0.20/conf/jk/
cp ../conf/workers.properties /opt/apache-tomcat-6.0.20/conf/jk/
Use subversion to check out the latest mod_auth_cas source (note we require the latest code from trunk - v1.0.8 will not work).
cd /root
svn co https://source.jasig.org/cas-clients/mod_auth_cas/trunk mod_auth_cas_trunk
cd mod_auth_cas_trunk
./configure; make; make install
NOTE: It might be a better idea to check out a release version, one that is tagged, as trunk might not be in a consistent way or might not even compile. For example tag '1.0.9.1' in '
https://source.jasig.org/cas-clients/mod_auth_cas/tags/mod_auth_cas-1.0.9.1/
' seems to work well.
We create a directory for mod_auth_cas to store cookie data. Note that this must be writeable by the apache user.
mkdir /tmp/cas
chown apache:apache /tmp/cas
chmod 0700 /tmp/cas
Now let's configure our modules.
In /etc/httpd/conf/httpd.conf make sure that ServerName is set to the full DNS name and port number through which your Apache HTTP Server will be reached by the outside world. This is important, because mod_auth_cas embeds this name into the URLs it generates.
ServerName your.server.com:80
Configure mod_jk by creating the file /etc/httpd/conf.d/mod_jk.conf with the following contents. This will mount the alfresco, share and examples applications on port 80 of the HTTP server. We mount the examples application, as it is very useful for diagnostics, as we shall see later.
<IfModule !mod_jk.c>
LoadModule jk_module '/usr/lib/httpd/modules/mod_jk.so'
</IfModule>
JkWorkersFile '/opt/apache-tomcat-6.0.20/conf/jk/workers.properties'
JkLogFile '/opt/apache-tomcat-6.0.20/logs/mod_jk.log'
JkLogLevel emerg
JkMount /alfresco ajp13
JkMount /alfresco/* ajp13
JkMount /share ajp13
JkMount /share/* ajp13
JkMount /examples ajp13
JkMount /examples/* ajp13
Now configure mod_ssl by editing /etc/httpd/conf.d/ssl.conf by adding the following lines near the end, just before the closing </VirtualHost> tag in order to mount the cas and examples applications on the HTTPS port. Note that we also switch on client certificate verification and set the SSLCACertificatePath so that our CA certificate will be trusted by Apache. We set the SSLOptions necessary to ensure that Apache will forward client certificate information to Tomcat.
JkMount /cas ajp13
JkMount /cas/* ajp13
JkMount /examples ajp13
JkMount /examples/* ajp13
SSLVerifyClient optional
SSLCACertificatePath /etc/pki/tls/certs/
SSLOptions +StdEnvVars +ExportCertData
Finally, configure mod_auth_cas by creating a file /etc/httpd/conf.d/mod_auth_cas.conf with the following contents. This will ensure the alfresco, share and examples applications are protected by CAS. Remember to edit the host name in CASLoginURL and CASValidateURL appropriately.
LoadModule auth_cas_module modules/mod_auth_cas.so
CASCookiePath /tmp/cas/
CASLoginURL https://your.server.com/cas/login
CASValidateURL https://your.server.com/cas/serviceValidate
CASValidateServer Off
CASDebug On
<LocationMatch ^/alfresco/(?!service/|service$|webdav/|webdav$|s/|s$|scripts/|css/|images/).*>
AuthType CAS
AuthName 'CAS'
require valid-user
CASScope /alfresco
</LocationMatch>
<Location /share>
AuthType CAS
AuthName 'CAS'
require valid-user
CASScope /share
</Location>
<Location /examples>
AuthType CAS
AuthName 'CAS'
require valid-user
CASScope /examples
</Location>
This will get the very latest Alfresco code and build and install the alfresco and share applications in to Tomcat.
cd /root
svn co http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/ alfresco_head
cd alfresco_head/root
ant incremental-tomcat
Now let's configure the alfresco app. Create a file /opt/apache-tomcat-6.0.20/shared/classes/alfresco-global.properties with the following lines. Note that we are using the new External authentication subsystem in our authentication chain, which will use the username passed by mod_auth_cas as request.getRemoteUser() as the Alfresco user.
dir.root=/opt/alfresco/alf_data
authentication.chain=external1:external
Make a root directory for the Alfresco application
mkdir -p /opt/alfresco/alf_data
Create a database for the Alfresco application by issuing the following commands to mysql:
drop database if exists alfresco;
create database alfresco default character set utf8 collate utf8_bin;
grant all on alfresco.* to alfresco identified by 'alfresco';
To configure the share app (See Alfresco_Share_SSO_using_NTLM or Alfresco_Share_using_external_SSO)
on 3.2:
cp projects/slingshot/config/alfresco/web-extension/webscript-framework-config-custom.xml.sample $CATALINA_HOME/shared/classes/alfresco/web-extension/webscript-framework-config-custom.xml
on 3.3:
tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml.sample
Now edit
on 3.2:
/opt/apache-tomcat-6.0.20/shared/classes/alfresco/web-extension/webscript-framework-config-custom.xml
or on 3.3:
tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml
and uncomment this section. Edit endpoint-url so that it points to the public address of the alfresco web app, through the Apache HTTP server.
<config evaluator='string-compare' condition='Remote'>
<remote>
<keystore>
<path>alfresco/web-extension/alfresco-system.p12</path>
<type>pkcs12</type>
<password>alfresco-system</password>
</keystore>
<connector>
<id>alfrescoCookie</id>
<name>Alfresco Connector</name>
<description>Connects to an Alfresco instance using cookie-based authentication</description>
<class>org.alfresco.connector.AlfrescoConnector</class>
</connector>
<endpoint>
<id>alfresco</id>
<name>Alfresco - user access</name>
<description>Access to Alfresco Repository WebScripts that require user authentication</description>
<connector-id>alfrescoCookie</connector-id>
<endpoint-url>https://your.server.com/alfresco/wcs</endpoint-url>
<identity>user</identity>
<external-auth>true</external-auth>
</endpoint>
</remote>
</config>
Note that the scheme in the <endpoint-url> parameter is HTTPS: this is because we want to have the proxy do a client authenticate over SSL based on the client certificate. The proxy user can then be passed to the alfresco back-end using the AJP protocol.
Keep in mind that, as stated in this forum post, activating external
authentication makes Alfresco accept external authentication tokens, so you must make sure that no other client than the authorized
Apache HTTP server can access it through HTTP or AJP.
I guess binding the AJP connector to localhost and disabling HTTP tomcat connectors should be enough.
Note: this security issue applies only if you have
external.authentication.proxyUserName
blank. If you use a non blank
external.authentication.proxyUserName
and SSL client certificate authentication, as described in this wiki page, that security hole does not exist.
First, start up the servers and check for errors in their logs.
catalina.sh start
/etc/init.d/httpd start
Now let's make sure CAS is authenticating us properly.
Browse to http://your.host.com/examples/jsp/snp/snoop.jsp
You should be redirected to the CAS login page. When you enter a valid LDAP username and password, you should be redirected back to the 'Snoop' JSP sample.
It should display, among other attributes, the name of the user you logged in as in the 'Remote User' field.
You might also want to ensure that CAS is also authenticating Alfresco Share's client certificate correctly. To do this, install alfresco-system.p12 into your browser, delete all your cookies and then navigate to snoop.jsp again. This time, you should see alfresco-system as the 'Remote User' without even being prompted for a username and password.
If this is all working then you are ready to try out the Alfresco Explorer and Share applications at
http://your.host.com/alfresco and
http://your.host.com/share
Remember to remove the alfresco-system certificate from your browser before you do so
If not, then carefully check all Apache HTTP Server and Tomcat log files, and set DEBUG logging in your CAS log4j.properties if necessary.
The following were some experiences setting this up on Ubuntu 9.04, and may help diagnose problems.
There are a number of potential issues that can come up if things are not followed absolutely correctly for your platform. For instance, creating the SSL certificates and the PKCS12 keystore on Ubuntu is probably done better by following the instructions at the Ubuntu OpenSSL Community Page or using CA.pl (details below).
Setting up your CA and certificates properly is, of course, crucial to having this method work. This is easy to tell in Step 7:
mkdir ~/newCA
cd ~/newCA
cp /usr/lib/ssl/misc/CA.pl .
chmod +x CA.pl
unset OPENSSL_CONF # so that we use the default /etc/ssl/openssl.cnf file
# The Subject/Common-Name here should be your authority name. Eg. My Company Certificate Authority
./CA.pl -newca # creates cacert.pem and cakey.pem
# The Subject/Common-Name here MUST be the host's external DNS name. Eg. my-host.myco.com
./CA.pl -newreq-nodes # creates the server request, with the -nodes option so no apache password prompt
./CA.pl -signreq # creates a signed certificate with the cacert created earlier
cp demoCA/cacert.pem /etc/ssl/certs/
cp demoCA/private/cakey.pem /etc/ssl/private/
mv newcert.pem /etc/ssl/certs/localhost.pem
mv newkey.pem /etc/ssl/private/localhost.key
# The Subject/Common-Name here MUST be alfresco-system
./CA.pl -newreq # create the alfresco certificate request
./CA.pl -signreq # create signed certificate
./CA.pl -pkcs12 'alfresco-system' # create the alfresco-system keystore/certificate.
# Make sure that the export password is set and it's
# the same as what you set in your webscript-framework-config-custom.xml
mv newcert.pem /etc/ssl/certs/alfresco-system.crt
mv newkey.pem /etc/ssl/private/alfresco-system.key
mv newcert.p12 <alfresco-path>/tomcat/shared/classes/alfresco/web-extension/alfresco-system.p12
Setting up Apache correctly is the other very important thing. Here are some instructions using the a2enmod scripts, and the associated configuration files.
SSLCACertificateFile /etc/ssl/certs/cacert.pem
SSLCertificateFile /etc/ssl/certs/localhost.pem
SSLCertificateKey /etc/ssl/private/localhost.key
# The SSL-enabled ajp worker nodes. casnode is the ajp13 cas-worker-node, defined in workers.properties
JkMount /cas* casnode
JkMount /examples* casnode
SSLVerifyClient optional
SSLCACertificateFile /etc/ssl/certs/cacert.pem
# Keeping SSLCACertificatePath causes the browser to go into a loading loop,
# so use the above SSLCACertificateFile instead
# SSLCACertificatePath /etc/ssl/certs
SSLOptions +StdEnvVars +ExportCertData
JkWorkersFile '/etc/apache2/workers.properties' # Or whatever your path is
JkLogFile '/var/log/apache2/mod_jk.log'
JkOptions +ForwardKeySize -ForwardDirectories
JkLogLevel info # or debug, emerg, error
# Your non-SSL mounts can be here
# alfnode is the ajp13 worker node for alfresco, and must be defined in workers.properties
JkMount /alfresco* alfnode
JkMount /share* alfnode
JkMount /examples* alfnode
(Note that if this is done right everything works. You do NOT need JkMountCopy On anywhere.)
Also note that if you specify the SSLCACertificatePath option for mod_ssl.conf, you may find that when you navigate to your https site the browser just keeps loading. The solution is to add SSLCACertificateFile /etc/ssl/certs/cacert.pem instead as described above.
Validated with 3.4 R 24232, Java 1.6.0_u21, Tomcat 6.0.29, Mysql 5.1 and options above
Any issues with Alfresco or share not getting the correct user name - use the snoop.jsp and check the details as advised above.
There are mainly two possible strategies to wire Share to Alfresco.
In this wiki, the first strategy is presented.
We introduce below the two strategies and their pros and cons.
center|500px
The Share data flow indicated in blue goes through Apache twice:
center|500px
The Share data flow indicated in blue goes through Apache only once:
The direct strategy is easier to set up and have one network hop less than the indirect strategy (and that hop involves encryption using certs). It should in theory thus be a bit faster than the indirect strategy.
However, to use the direct strategy you need to make sure that your Alfresco server is well locked down, i.e. that no direct connection to port 8080 are possible. In other words, you have to enforce that all connections have to go through apache. This can be achieved easily with a firewall rule (like iptables on Linux). If the setup is not well locked, then a malicious user could log as any user just forging the auth header with the user he wants to log in as.
Authentication
Single Sign On
CAS