cancel
Showing results for 
Search instead for 
Did you mean: 

Share with mod_auth_cas not working

jmwarfe
Champ in-the-making
Champ in-the-making
I'm in the process of trying to get Community Edition 3.2r to talk with my university's CAS server. So far I have followed the wiki page instructions for external authentication and can now log into the Alfresco explorer using SSO however Share gives me the following error below. I'm wondering if my shared/classes/alfresco/web-extension/webscript-framework-config-custom.xml is configured properly and being read or if there is an issue with my SSL certificates. Any thoughts as to what might be the problem?

Thanks in advance!

Tomcat Error:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: org.alfresco.web.site.exception.RequestContextException: Exception running UserFactory in HttpRequestContextFactory
   org.alfresco.web.site.servlet.DispatcherServlet.service(DispatcherServlet.java:146)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

org.alfresco.web.site.exception.RequestContextException: Exception running UserFactory in HttpRequestContextFactory
   org.alfresco.web.site.DefaultRequestContextFactory.newInstance(DefaultRequestContextFactory.java:117)
   org.alfresco.web.site.FrameworkHelper.initRequestContext(FrameworkHelper.java:202)
   org.alfresco.web.site.servlet.DispatcherServlet.service(DispatcherServlet.java:142)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

org.alfresco.web.site.exception.UserFactoryException: Unable to retrieve user from repository
   org.alfresco.web.site.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:252)
   org.alfresco.web.site.UserFactory.faultUser(UserFactory.java:176)
   org.alfresco.web.site.UserFactory.faultUser(UserFactory.java:110)
   org.alfresco.web.site.DefaultRequestContextFactory.newInstance(DefaultRequestContextFactory.java:93)
   org.alfresco.web.site.FrameworkHelper.initRequestContext(FrameworkHelper.java:202)
   org.alfresco.web.site.servlet.DispatcherServlet.service(DispatcherServlet.java:142)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

org.json.JSONException: A JSONObject text must begin with '{' at character 1 of <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>…..</html>
   org.json.JSONTokener.syntaxError(Unknown Source)
   org.json.JSONObject.<init>(Unknown Source)
   org.json.JSONObject.<init>(Unknown Source)
   org.alfresco.web.site.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:165)
   org.alfresco.web.site.UserFactory.faultUser(UserFactory.java:176)
   org.alfresco.web.site.UserFactory.faultUser(UserFactory.java:110)
   org.alfresco.web.site.DefaultRequestContextFactory.newInstance(DefaultRequestContextFactory.java:93)
   org.alfresco.web.site.FrameworkHelper.initRequestContext(FrameworkHelper.java:202)
   org.alfresco.web.site.servlet.DispatcherServlet.service(DispatcherServlet.java:142)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)



webscript-framework-config-custom.xml:
<alfresco-config>
  
   <!– Overriding endpoints to reference a remote Alfresco server –>
   <!–
   <config evaluator="string-compare" condition="Remote">
      <remote>

         <endpoint>
            <id>alfresco-noauth</id>
            <name>Alfresco - unauthenticated access</name>
            <description>Access to Alfresco Repository WebScripts that do not require authentication</description>
            <connector-id>alfresco</connector-id>
            <endpoint-url>http://yourserver:8080/alfresco/s</endpoint-url>
            <identity>none</identity>
         </endpoint>

         <endpoint>
            <id>alfresco</id>
            <name>Alfresco - user access</name>
            <description>Access to Alfresco Repository WebScripts that require user authentication</description>
            <connector-id>alfresco</connector-id>
            <endpoint-url>http://yourserver:8080/alfresco/s</endpoint-url>
            <identity>user</identity>
         </endpoint>

         <endpoint>
            <id>alfresco-feed</id>
            <name>Alfresco Feed</name>
            <description>Alfresco Feed - supports basic HTTP authentication</description>
            <connector-id>http</connector-id>
            <endpoint-url>http://yourserver:8080/alfresco/s</endpoint-url>
            <basic-auth>true</basic-auth>
            <identity>user</identity>
         </endpoint>
         
      </remote>
   </config>
   –>
   
   <!– Overriding endpoints to reference an Alfresco server with external SSO or NTLM enabled –>
   <!– NOTE: For NTLM, the NTLM Authentication Filter must also be enabled in share web.xml –>
   <!– NOTE: if utilising a load balancer between web-tier and repository cluster, the "sticky –>
   <!–       sessions" feature of your load balancer must be used –>
   <config evaluator="string-compare" condition="Remote" replace="true">
        <remote>
            <!– SSL client certificate + trusted CAs. Optionally used to authenticate share to an external SSO system such as CAS –>
            <keystore>
                <path>/opt/Alfresco/tomcat/shared/classes/alfresco/web-extension/alfresco-system.p12</path>
                <type>pkcs12</type>
                <password>alfresco</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>http://<hostname removed>/alfresco/wcs</endpoint-url>
                <identity>user</identity>
                <external-auth>true</external-auth>
            </endpoint>
           
        </remote>
    </config>
</alfresco-config>
28 REPLIES 28

matthias
Champ in-the-making
Champ in-the-making
Matthias, I wonder how you got your Share to send out the certificate. It seems (based on my logs) that I'm actually failing the X509CredentialsAuthenticationHandler in login-webflow and going on to the viewLoginForm action. But can't understand why. Do you have any suggestions? Did you have this problem before and solve the certificate handling somehow? Thanks much for any help.

cybertoast: I configured everything as described in http://wiki.alfresco.com/wiki/Alfresco_With_mod_auth_cas (without Maven).

Except one thing: I added the following to /etc/apache2/httpd.conf:

SSLVerifyClient optional
SSLCACertificateFile /etc/ssl/certs/cacert.pem
SSLOptions +StdEnvVars +ExportCertData

This was the only way to make it work. Otherwise Apache seems not to send the incoming certificate properly.
I got the same error as you before I made these changes, so maybe that solves your problem.

Try at first if you can login to the snoop.jsp example (bottom of wiki article) via the certificate. If this works, you're on a good way.

Matthias.

matthias
Champ in-the-making
Champ in-the-making
Do you feel up to adding some additional logging to

org.alfresco.connector.RemoteClient.service(URL, InputStream, OutputStream, HttpServletRequest, HttpServletResponse, ResponseStatus)

?

If we could see what URLs are being called, what redirects are happening, what cookies are being returned and what status codes are being received, we might be able to work out what's going wrong!


Ok, I tried to set the logging but I only get results if I use org.alfresco.connector.RemoteClient=debug - going further like

org.alfresco.connector.RemoteClient.service gives no result. Am I doing something wrong?

The result with RemoteClient=debug

16:25:37,223 DEBUG [org.alfresco.connector.RemoteClient] Executing (GET) https://app01.company.de/alfresco/wcs/webframework/content/metadata?user=matthias.name%40company.de
16:25:37,225 DEBUG [org.alfresco.connector.RemoteClient]  - OutputStream supplied - will stream response…
16:25:37,305 DEBUG [org.alfresco.connector.RemoteClient] Setting cookie header: MOD_AUTH_CAS_S=b5d6a2524928d27bd5ade0bed30742e6;CASTGC=TGT-25-7CNalUs5KSroXN3zXgWPcN0DchY0CSttWwqx3Wk4uniP05ZVsE-app01.company.de
16:25:37,502 DEBUG [org.alfresco.connector.RemoteClient] Response status code: 401
16:25:37,502 DEBUG [org.alfresco.connector.RemoteClient] Response encoding: Content-Type: text/html; charset=iso-8859-1

That's it. Not very helpful. 😕

cybertoast
Champ in-the-making
Champ in-the-making
Matthias, Thanks very much for your response. I've actually tried that, but still have no success on the client authentication part.
This is what I had to do to just get things sort of working:

1. Apache default-ssl file (I'm using Ubuntu, so this may just be the httpd.conf file's :443 virtualhost on other systems):

SSLCertificateFile /etc/ssl/certs/localhost.crt
SSLCertificateKeyFile /etc/ssl/private/localhost.pem
In mod-enabled/ssl.conf, I added the JkMount /cas .. stuff, but also had to add JkMountCopy On:

JkMountCopy On
JkMount /cas casnode
JkMount /cas/* casnode
JkMount /examples casnode
JkMount /examples/* casnode
SSLVerifyClient optional
SSLCACertificateFile /etc/ssl/certs/cacert.pem
SSLOptions +StdEnvVars + ExportCertData

2. In my tomcat/conf/server.xml I had to add the keystore (otherwise casserver fails to start up, with errors about jsse.invalid_ssl_conf):

   <Connector port="8444" protocol="HTTP/1.1" SSLEnabled="true"
               maxHttpHeaderSize="8192" minSpareThreads="25" maxSpareThreads="75"
               maxThreads="150" scheme="https" secure="true"
               sslProtocol="TLS" connectionTimeout="20000"
               clientauth="true"
               keystoreFile="/etc/ssl/alfresco-system.p12"
               keystoreType="PKCS12" keystorePass="password"
               truststoreFile="/etc/ssl/alfresco-system.p12"
               truststorePass="password" truststoreType="PKCS12"
   />

When I try to connect to the tomcat server directly (http://myhost:8444/cas/login) I get a "SSL peer cannot verify your certificate. (Error code: ssl_error_bad_cert_alert)" from firefox. This is because I've set clientauth="true". If I set clientauth="want", then I get the CAS login form.

So basically I'm unable to get the client authentication using the pkcs12 alfresco-system.p12 keystore.

I thought maybe this was because the alfesco-system cert has a CN of alfresco-system, and so changed this to my DNS. But did not make any difference.

I also tried to import the /etc/ssl/certs/cacert.pem into my keystore using keytool:

keytool –import -alias alfresco-system -keystore /etc/ssl/keystore -file /etc/ssl/certs/cacert.pem
But this caused jsse.invalid_ssl_conf and "no available certifice or key corresponds to the ssl cipher suites which are enabled" during startup of casserver.

I'm sure there's something relatively simple that I'm missing, but just can't figure out what. The fact that I've been staring at this for several days is probably not helping either Smiley Happy

Thanks for your help, anyway!

dward
Champ on-the-rise
Champ on-the-rise
mathias

That at least tells us that it's getting a status 401 response from alfresco, even for an authenticated request with a CAS cookie in place.

We believe this may mean that the external authentication subsystem has become broken, ironically due to recent changes made to support multi tennancy.

I have logged

https://issues.alfresco.com/jira/browse/ETHREEOH-3265

cybertoast. You are deviating away from the supported instructions and I can't help you. You shouldn't be using the keystore at all with tomcat - this should be configured in apache and you should switch tomcat authentication off as it says in the instructions. I also hope you started with a virgin tomcat zip as the installation requires and not some Ubuntu packaged version. And we don't need JkMountCopy On.

cybertoast
Champ in-the-making
Champ in-the-making
dward, thanks for the response. My tomcat is the zip file from apache (apache-tomcat-6.0.20.tar.gz), not the ubuntu packaged one.
When using the standard server.xml (without keystore definitions), but with tomcatAuthentication="false", I get:

SEVERE: Failed to load keystore type JKS with path /root/.keystore due to /root/.keystore (No such file or directory)java.io.FileNotFoundException: /root/.keystore (No such file or directory)
  at java.io.FileInputStream.open(Native Method)
  at java.io.FileInputStream.<init>(FileInputStream.java:106)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:341)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:263)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:473)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:413)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:129)
  at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:503)
  at org.apache.tomcat.util.net.JIoEndpoint.start(JIoEndpoint.java:526)
  at org.apache.coyote.http11.Http11Protocol.start(Http11Protocol.java:203)
  at org.apache.catalina.connector.Connector.start(Connector.java:1131)
  at org.apache.catalina.core.StandardService.start(StandardService.java:531)
  at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
  at org.apache.catalina.startup.Catalina.start(Catalina.java:583)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
  at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Nov 4, 2009 12:28:14 PM org.apache.coyote.http11.Http11Protocol start
SEVERE: Error starting endpoint
java.io.FileNotFoundException: /root/.keystore (No such file or directory)
  at java.io.FileInputStream.open(Native Method)
  at java.io.FileInputStream.<init>(FileInputStream.java:106)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:341)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:263)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:473)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:413)
  at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:129)
  at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:503)
  at org.apache.tomcat.util.net.JIoEndpoint.start(JIoEndpoint.java:526)
  at org.apache.coyote.http11.Http11Protocol.start(Http11Protocol.java:203)
  at org.apache.catalina.connector.Connector.start(Connector.java:1131)
  at org.apache.catalina.core.StandardService.start(StandardService.java:531)
  at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
  at org.apache.catalina.startup.Catalina.start(Catalina.java:583)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
  at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

This is the ONLY reason I deviated from the wiki - I could not figure out any other way to make this work (and basically followed the tomcat instructions on the CAS site, the one where you explicitly say "don't worry about tomcat configuration steps"). Smiley Happy

Anyway, I don't have a keystore file by default (the /root/.keystore), so how to proceed?

Again, thanks. I'm completely flummoxed and have had no luck getting this to work, so any help is hugely appreciated!

cybertoast
Champ in-the-making
Champ in-the-making
Crap, I'm an idiot! Sorry, I had uncommented the SSL portion of the original tomcat server.xml file. SO SO SORRY! Ok, I'm trying it all out from scratch again and let's see if it's all just because of my stupidity!

cybertoast
Champ in-the-making
Champ in-the-making
Ok, starting from scratch, this is what happens:

1. If I try to navigate to http://myhost/cas/login, I get login screen. https://myhost/cas/login gives me

Not Found
the requested URL /cas/login was not found on this server
The only way to get this to work is to add JkMountCopy On in my default-ssl virtualhost. Adding this to my ssl.conf also does not work.
I had to change the SSLCACertificatePath /etc/ssl/certs/ to SSLCACertificateFile /etc/ssl/certs/cacert.pem (like matthias suggested as well), since otherwise Firefox and Safari both just hang on "loading…" connecting to the URL.

I set the SSLCertificateFile to /etc/ssl/certs/localhost.crt and SSLCertificateKeyFile to /etc/ssl/private/localhost.key. These are the cert/key generated in Step 3 of the wiki instructions.

2. I have steps 2, 3 and 4 completed, and have Apache, CASServer and all certificates in place. mod-jk redirects my requests to /cas/login. Trying the snoop.jsp example redirects me to /cas/login and my ldap auth works.

3. Trying out client authentication by importing the alfresco-system.p12 keystore into Firefox, cleaning out cookies and going back to http://myhost/examples/jsp/snp/snoop.jsp takes me to https://myhost/cas/login?service=
So importing the alfresco-system.p12 keystore into Firefox does not seem to have any effect Smiley Sad

Any ideas?

matthias
Champ in-the-making
Champ in-the-making
Hmm, seems you should get CAS-Server working at first.

- You don't need JkMountCopy at all. (btw: I'm using Ubuntu as well)
- Use "JkMount /cas* worker1" in your SSL VHost.
- Create /etc/apache/workers.properties with the following:

worker.list=worker1
worker.default.port=8009
worker.default.host=localhost
worker.default.type=ajp13
worker.default.lbfactor=1

Put the following in /etc/apache/httpd.conf

JkWorkersFile /etc/apache2/workers.properties

# Where to put jk logs
JkLogFile /var/log/apache2/mod_jk.log

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize -ForwardDirectories

# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"


That is enough to make Apache work with CAS.

After that you can protect some dirs with mod_auth_cas.
Try that with the /examples directory of Tomcat. Check, if you can see your username there.

cybertoast
Champ in-the-making
Champ in-the-making
dward,
* Removed all JkMountCopy On
* Removed my JkMount /cas* casnode from /etc/apache2/mods-enabled/ssl.conf and moved JkMount /cas* casnode to /etc/apache2/sites-enabled/default-ssl
* Left JkMount /examples* casnode in /etc/apache2/mods-enabled/ssl.conf
* Added your suggestions to httpd.conf (basically it was an empty file, and now it only has the stuff you suggested)
* Removed JkWorkersFile and JkLogFile from /etc/apache2/mods-enabled/jk.conf (since they're now in httpd.conf)

My /etc/apache2/workers.properties file:

worker.list=ajp12, ajp13, casnode, alfnode  # I know I only need casnode and alfnode
worker.casnode.port=8009
worker.casnode.host=myhost
worker.casnode.type=ajp13
worker.casnode.lbfactor=1
worker.alfnode.port=8010
worker.alfnode.host=myhost
worker.alfnode.type=ajp13
worker.inprocess.type=jni
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar
worker.inprocess.cmd_line=start
worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jvm.dll
worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr

This makes CAS work with apache. I believe the addition of the JkMount /cas* casnode into the default.ssl file is what made the difference. (Maybe because sites-enabled is what's included last in apache2.conf?).

* Ensured that there is nothing in Your Certificates in Firefox's Certificate Manager.
* Go to http://myhost/examples/jsp/snp/snoop.jsp -> Get CAS login form
* Clear all cookies, import alfresco-system.p12 into Firefox's Your Certificates, and I get the CAS login form, same as before. And in my CAS log is:

2009-11-04 18:06:19,472 DEBUG [org.jasig.cas.adaptors.x509.web.flow.X509CertificateCredentialsNonInteractiveAction] - <Certificates not found in request.>

Thanks VERY VERY much for helping with this!

matthias
Champ in-the-making
Champ in-the-making
* Ensured that there is nothing in Your Certificates in Firefox's Certificate Manager.
* Go to http://myhost/examples/jsp/snp/snoop.jsp -> Get CAS login form
* Clear all cookies, import alfresco-system.p12 into Firefox's Your Certificates, and I get the CAS login form, same as before. And in my CAS log is:

2009-11-04 18:06:19,472 DEBUG [org.jasig.cas.adaptors.x509.web.flow.X509CertificateCredentialsNonInteractiveAction] - <Certificates not found in request.>

Thanks VERY VERY much for helping with this!


cybertoast, what you didn't tell me:
- Can you login via CAS to snoop.jsp (without certificate, only with username+pass!)?
- If yes, do you see your username there?

Do this first. After that, we can check the certificate stuff.