[MNT-15795] CAS authentication no longer works Created: 19-Jun-15  Updated: 03-Oct-16  Resolved: 21-Apr-16

Status: Closed
Project: Service Packs and Hot Fixes
Component/s: Repository Authentication and SSO, Share Application
Affects Version/s: 5.0
Fix Version/s: 5.0.4

Type: Bug
Reporter: Ian Wright (Inactive) Assignee: Closed Bugs
Resolution: Fixed Votes: 1
Labels: None
Remaining Estimate: 0 minutes
Time Spent: 1 week, 4 days, 4 hours
Original Estimate: Not Specified

Attachments: File CAS.patch    
Issue Links:
Duplicate
duplicates ALF-21476 External authentication with REMOTE_USER Closed
Related
Bug Priority:
Category 2
Build Location: https://releases.alfresco.com/Enterprise-5.0/5.0.4/build-00030/ALL/
Regression Since:
4.2
Patch Attached:
Yes

 Description   

Changes to SSO mean that it is no longer possible to use CAS authentication (and presumably other forms of SSO)

All the information you need should be in this forum post:
https://forums.alfresco.com/comment/157861#comment-157861

Complete thread for reference http://forums.alfresco.com/forum/installation-upgrades-configuration-integration/authentication-ldap-sso/alfresco-community-50d



 Comments   
Comment by Kevin Roast [X] (Inactive) [ 08-Mar-16 ]

Ian Wright - Our investigation team have confirmed this is working OK on the following versions: 4.1.N, 4.2.N, 5.0.N (i.e. all supported Enterprise service pack versions) and also working on 5.1.0 Enterprise and 5.1.e Community. We also confirmed it is NOT working in 5.0.d as you said. So we are happy this is fixed in latest Community and was a transient error in 5.0.d release.

Comment by Ian Wright (Inactive) [ 11-Mar-16 ]

I've just tried an upgrade to SDK 2.2.0 and I'm afraid that I can't get it to work so I think it is still broken
https://github.com/wrighting/alfresco-cas branch 5.1.e
As it stands it works although there is a error message in the logs but this is with my patched version of the SlingshotAlfrescoConnector, if I change it to use the org.alfresco version then I am sent to the normal login box.
If you want a login for my test CAS server then I am happy to provide one.

Comment by Alexandra Leahu [X] (Inactive) [ 21-Mar-16 ]

I created a clean Alfresco application using SDK 2.2 and tried to reproduce the issue using simple external authentication (without CAS). The issue is indeed reproducible using the following block(taken from the alfresco-cas project ) in share-amp\src\mail\resources\META-INF\share-config-custom.xml:

 <config evaluator="string-compare" condition="Remote">
      <remote>
     <connector>
            <id>alfrescoCookie</id>
            <name>Alfresco Connector</name>
            <description>Connects to an Alfresco instance using cookie-based authentication</description>
            <class&gt;org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class&gt;
            <userHeader>X-Alfresco-Remote-User</userHeader>
         </connector>

         <connector>
            <id>alfrescoHeader</id>
            <name>Alfresco Connector</name>
            <description>Connects to an Alfresco instance using header and cookie-based authentication</description>
            <class&gt;org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class&gt;
            <userHeader>X-Alfresco-Remote-User</userHeader>
         </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://localhost:8080/alfresco/wcs</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>

         <endpoint>
            <id>alfresco-feed</id>
            <parent-id>alfresco</parent-id>
            <name>Alfresco Feed</name>
            <description>Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet</description>
            <connector-id>alfrescoHeader</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/wcs</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>

         <endpoint>
            <id>alfresco-api</id>
            <parent-id>alfresco</parent-id>
            <name>Alfresco Public API - user access</name>
            <description>Access to Alfresco Repository Public API that require user authentication.
                         This makes use of the authentication that is provided by parent 'alfresco' endpoint.</description>
            <connector-id>alfrescoHeader</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/api</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>
      </remote>
   </config>

It looks like this is a configuration issue: the alfrescoCookie connector shouldn’t reference the userHeader. The issue boils down to the userHeader property not being initialized on SSOAuthenticationFilter, and because of this the remote user is not extracted from the header. Using the following config block the context is properly initialized and simple external authentication worked:

<config evaluator="string-compare" condition="Remote">
    <remote>
         <connector>
            <id>alfrescoCookie</id>
            <name>Alfresco Connector</name>
            <description>Connects to an Alfresco instance using cookie-based authentication</description>
            <class&gt;org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class&gt;
         </connector>

         <connector>
            <id>alfrescoHeader</id>
            <name>Alfresco Connector</name>
            <description>Connects to an Alfresco instance using header and cookie-based authentication</description>
            <class&gt;org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class&gt;
            <userHeader>X-Alfresco-Remote-User</userHeader>
         </connector>

         <endpoint>
            <id>alfresco</id>
            <name>Alfresco - user access</name>
            <description>Access to Alfresco Repository WebScripts that require user authentication</description>
            <connector-id>alfrescoHeader</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/wcs</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>

         <endpoint>
            <id>alfresco-feed</id>
            <parent-id>alfresco</parent-id>
            <name>Alfresco Feed</name>
            <description>Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet</description>
            <connector-id>alfrescoHeader</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/wcs</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>

         <endpoint>
            <id>alfresco-api</id>
            <parent-id>alfresco</parent-id>
            <name>Alfresco Public API - user access</name>
            <description>Access to Alfresco Repository Public API that require user authentication.
                         This makes use of the authentication that is provided by parent 'alfresco' endpoint.</description>
            <connector-id>alfrescoHeader</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/api</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>
      </remote>
   </config>

Note that, besides removing the <userHeader>X-Alfresco-Remote-User</userHeader> block from alfrescoCookie, I also changed the alfresco endpoint to use the alfrescoHeader connector. From the documentation I wasn't able to find a reason for the alfrescoCookie connector to reference the header property.

Although this seems to fix the issue for simple external authentication, I haven’t tested the CAS project, and I'm not sure if this updated config would work for that setup. Please provide the credentials to the test CAS server, in order to make sure the fix works for that scenario as well.

Comment by Kevin Roast [X] (Inactive) [ 22-Mar-16 ]

Ian Wright are you able to try this config, and if it fails to help, access to your CAS test server would be very much appreciated, thanks!

Comment by Alexandra Leahu [X] (Inactive) [ 22-Mar-16 ]

I cloned the project (branch 5.1.e) and tried to run the project locally, but ran into some issues. https://wrighting.org/sso seems to be used instead of https://tech.wrighting.org/sso, I updated the config files to use https://tech.wrighting.org/sso but I still get an error after entering the credentials provided (this is without applying the share-config-xml changes):

2016-03-22 18:12:30,415  ERROR [alfresco.web.site] [http-bio-8080-exec-5] java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
 javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1301)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
        at org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:429)
        at org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:41)
        at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:193)
        at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:204)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:164)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at sun.security.ssl.InputRecord.read(InputRecord.java:482)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
        ... 30 more

It seems that there might be some additional configuration that I have to do on my machine(or maybe on the CAS one) in order to be able to test this properly.
Ian Wright have you tried the above configuration, that uses the org.alfresco.web.site.servlet.SlingshotAlfrescoConnector and with the userHeader removed from the alfrescoCookie connector?

Comment by Ian Wright (Inactive) [ 22-Mar-16 ]

Are you sure that you're using the 5.1.e branch? That would explain the CAS config

git status
On branch 5.1.e
Your branch is up-to-date with 'origin/5.1.e'.

In the pom.xml you should see:

       <parent>
                <groupId>org.alfresco.maven</groupId>
                <artifactId>alfresco-sdk-parent</artifactId>
                <version>2.2.0</version>
        </parent>

           <!-- CAS settings for web.xml -->
                <alfresco.server.name>http://localhost:8080</alfresco.server.name>
                <share.server.name>http://localhost:8080</share.server.name>
                <cas.server.prefix>https://tech.wrighting.org/sso</cas.server.prefix>
                <cas.logout.dest.url>http://wrighting.org</cas.logout.dest.url>

        </properties>

I have tried the above configuration with org.alfresco.web.site.servlet.SlingshotAlfrescoConnector and it just sent me to the Alfresco login page.

I didn't need to do any additional configuration on my machine (using Ubuntu) the main thing is to be able to connect to the CAS server from tomcat (not the browser)

A quick google seems to indicate it might be a compatibility problem with the cipher suites which could be down to java version

java -version
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

FWIW the server side apache config is:

SSLProtocol +TLSv1.1 +TLSv1.2
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"

I can see you logging in between 16:10 and 16:15 but that the service ticket is not validated - this is when the CAS client code makes a call to the CAS server i.e. your tomcat talking to my server.
You can test the connection from the command line with curl like this:

curl https://tech.wrighting.org/sso/p3/serviceValidate?ticket=ST-14-2VIY3NyugdGO9AWb9ku5-wrighting.org

If everything is OK you should get a response like this (as the ticket isn't valid):

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
	<cas:authenticationFailure code='INVALID_REQUEST'>
		&#039;service&#039; and &#039;ticket&#039; parameters are both required
	</cas:authenticationFailure>
</cas:serviceResponse>
Comment by Alex Mukha [ 30-Mar-16 ]

Hi Ian Wright,could you please confirm that you are using the configuration provided by our official documentation:
http://docs.alfresco.com/community5.0/concepts/alf-modauthcas-home.html

Comment by Ian Wright (Inactive) [ 30-Mar-16 ]

I am not using the mod_auth_cas approach, which you can see from the github.

CAS is currently at version 4.2 and the documentation only supports version 3.3.5 of CAS, which is no longer supported.

There is also no release of mod_auth_cas since 2010, although there is some recent activity.

This is why I've created the github to provide an easy example of how to configure with supported CAS versions.

The approach I have taken will end up with the same result as if mod_auth_cas was used i.e. HttpServletRequest.getRemoteUser will return the name of the user

Variations on this approach have worked since version 3.4

Comment by Alexandra Leahu [X] (Inactive) [ 30-Mar-16 ]

Ian Wright This extra configuration step documented here might solve this, and send the user in the header, as expected by alfresco.
Can you confirm that you are using this - and if not, can you give it a try and let us know if the issue persists?

Comment by Ian Wright (Inactive) [ 30-Mar-16 ]

HttpServletRequest.getRemoteUser and/or HttpServletRequest.getPrincipal should be sufficient to provide the username and shouldn't need extra headers to be set.
The configuration step requires Apache and for the reasons above I'm not using that.

I think the problem is that in SlingshotAlfrescoConnector.applyRequestHeader the credentials as held in getCredentials().getProperty(Credentials.CREDENTIAL_USERNAME) are being ignored.
If I've read the code correctly (only a quick look...) then it shouldn't be necessary to extract the user from the request header at this point as that should already have been done earlier in the code and can be retrieved from the credentials property.

The github branch does appear to work after all, despite the log message

Comment by Alex Mukha [ 30-Mar-16 ]

Sorry Ian, if you are using an unsupported configuration we can't call this issue a bug. I admit that we should consider supporting a newer version of CAS.

I would like to convert this issue to an improvement. Could you please add a complete set of instructions you have used to set up CAS and Alfresco so that Project Management can decide if we can include such configuration to the supported list.

Thank you.

Comment by Ian Wright (Inactive) [ 30-Mar-16 ]

The supported configuration won't work either - it uses exactly the same code path

Comment by Alex Mukha [ 30-Mar-16 ]

Alexandra Leahu [X], could you please confirm that Alfresco works with CAS using the official instructions from docs.alfresco.com?

Thank you.

Comment by Ian Wright (Inactive) [ 31-Mar-16 ]

The patch I suggested draws on https://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/COMMUNITYTAGS/V4.2a/root/projects/slingshot/source/java/org/alfresco/web/site/servlet/SlingshotAlfrescoConnector.java

If for some reason you don't want to implement this patch then please can you explain why not.

Comment by Richard Esplin [X] (Inactive) [ 04-Apr-16 ]

Thank you Ian Wright for the effort you have put in to help us diagnose this issue. I want to clarify the approach we are taking.

Our intention is not to provide official support for CAS, but to make sure that our external authentication subsystem works correctly and in a general enough way that it can be successfully configured with CAS. We are concerned that the suggested patch could have side-effects for other users of the External Authentication subsystem, and so we want to make sure we fully understand the expected behavior.

It looks like there is a bug in our checking of the remote user in the request that we plan to fix. We will also remove the out-of-date CAS documentation (MNT-15966).

Once you get CAS configured so it works with 5.1, we hope that you will post instructions in the forums or to a blog so that others can adapt it to their CAS environments.

Thank you.

Comment by Ian Wright (Inactive) [ 11-Apr-16 ]

@Richard Esplin
Hi Richard,
I'm sure we want the same thing, consistent behaviour of the external authentication subsystem.
The reason for this report was that the subsystem obviously badly broke at some point between 5.0.c and 5.0.d and the suggested patch is to revert the behaviour back to how it worked in 5.0.c
I don't know the reason this changed between 5.0.c and 5.0.d so I can't be sure if reversion is the correct thing to do, but if it's not then it would be good to know why not - I don't want to put back something that shouldn't be there.
(My suspicion is that it might be related to ALF-21129)

Ultimately I don't want to get into the detail of this as all I care about is consistent behaviour, which means that HttpServletRequest.getRemoteUser and/or HttpServletRequest.getPrincipal will provide the external authentication details.

Hopefully this can be added to automated testing so this doesn't happen again - it is a big problem for me if this breaks.

I am giving a lightning talk about this subject at BeeCon.

When I have time I will update my public alfresco-cas github for 5.1 (which is already referenced from the forums and no doubt will be again.)

Comment by Richard Esplin [X] (Inactive) [ 09-May-16 ]

Ian Wright: I should have explained that my clarifications on how we want to support CAS were for my team. There were questions on whether we need to maintain an internal CAS environment, and how many CAS options we need to test.

It was nice to see you at BeeCon. I got pulled away during the lightning talks, but i hope to catch the recording (I'm hoping that is one that worked).

Thank you again for helping us to diagnose and fix this issue. The fix should be merged to HEAD soon.

Comment by Kevin Roast [X] (Inactive) [ 28-Jun-16 ]

FYI this is merged and will be in the Community release today.

Generated at Sat Aug 15 21:36:23 BST 2020 using Jira 7.13.15#713015-sha1:7c5ddd2c3e1709974ae9c48c17df8edd3919fe2c.