cancel
Showing results for 
Search instead for 
Did you mean: 

Share + Alfresco with SSO

mboorshtein
Champ in-the-making
Champ in-the-making
All,

I'm integrating Alfresco and Share with an SSO system that uses a reverse proxy and a filter that creates a header with the user's id and creates the UserPrincipal object with the user's Id.  This works great for Alfresco, however Share isn't working.  When I access share a few things happen:

1.  in the browser I get the following message:

org.springframework.extensions.surf.exception.UserFactoryException: Unable to create user - failed to retrieve user metadata:
   org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:177)
   org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:176)
   org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
   org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:203)
   org.springframework.extensions.surf.RequestContextUtil.initRequestContext(RequestContextUtil.java:107)
   org.springframework.extensions.surf.RequestContextUtil.initRequestContext(RequestContextUtil.java:54)
   org.alfresco.web.site.SlingshotPageViewResolver.lookupPage(SlingshotPageViewResolver.java:57)
   org.springframework.extensions.surf.mvc.PageViewResolver.canHandle(PageViewResolver.java:103)
   org.springframework.web.servlet.view.UrlBasedViewResolver.createView(UrlBasedViewResolver.java:370)
   org.springframework.web.servlet.view.AbstractCachingViewResolver.resolveViewName(AbstractCachingViewResolver.java:77)
   org.springframework.web.servlet.DispatcherServlet.resolveViewName(DispatcherServlet.java:1091)
   org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1040)
   org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
   org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
   org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
   org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
   org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:301)
   com.tremolosecurity.filter.AutoIDMFilter.doFilter(AutoIDMFilter.java:90)

2.  My alfresco service (its a stock 3.4.d install all on one server) shows the following request:

URL : 'http://localhost:8080/alfresco/s/webframework/content/metadata'
Method : 'GET'
Source IP : '127.0.0.1'
Source Port : '34303'
Header : 'user-agent=Jakarta Commons-HttpClient/3.1'
Header : 'host=localhost:8080'
Parameter : 'user=mboorshtein'

which appears to have a 401 response with the realm "Alfresco"

how do these two systems interact?  prior to integrating SSO (using org.alfresco.web.app.servlet.HTTPRequestAuthenticationFilter) I had no issues.  Is it looking for a service account or a header in the request?  is this configurable in Share?  Since its looking for the user mboorshtein share is getting the authentication context from the UserPrincipal?

Thanks
Marc
5 REPLIES 5

bbougon
Champ in-the-making
Champ in-the-making
Hello,

up

I do have the same kind of problems.

While trying to login to Share via SSO (Shibboleth uses SAML) I have theses Exceptions thrown :
org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
   org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:188)
   org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:176)
   org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
   org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:203)
   org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:176)
   org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:131)
   org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:349)
   org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:259)
   org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
   org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
   org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
   org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
   org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
   org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
   fr.cvf.web.site.servlet.CVFSSOAuthenticationFilter.doFilter(CVFSSOAuthenticationFilter.java:343)
cause mère

org.json.JSONException: A JSONObject text must begin with '{' at character 8
   org.json.JSONTokener.syntaxError(JSONTokener.java:413)
   org.json.JSONObject.<init>(JSONObject.java:180)
   org.json.JSONObject.<init>(JSONObject.java:420)
   org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:182)
   org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:176)
   org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
   org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:203)
   org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:176)
   org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:131)
   org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:349)
   org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:259)
   org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
   org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
   org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
   org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
   org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
   org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
   fr.cvf.web.site.servlet.CVFSSOAuthenticationFilter.doFilter(CVFSSOAuthenticationFilter.java:343)

Everything works perfectly on Explorer but not on Share and while I am debugging, it seems everything work fine for the Authentication part (see the bold part near the end) :

private void challengeOrPassThrough(FilterChain chain, HttpServletRequest req, HttpServletResponse res, HttpSession session) throws IOException, ServletException
    {
        try
        {
            // In this mode we can only use vaulted credentials. Do not proxy any request headers.
            Connector conn = connectorService.getConnector(this.endpoint, AuthenticationUtil.getUserId(req), session);
            ConnectorContext ctx = new ConnectorContext();
            Response remoteRes = conn.call("/touch", ctx);
            if (Status.STATUS_UNAUTHORIZED == remoteRes.getStatus().getCode())
            {
                if (logger.isDebugEnabled())
                {
                    logger.debug("Repository session timed out - restarting auth process…");
                }
               
                String authHdr = remoteRes.getStatus().getHeaders().get(HEADER_WWWAUTHENTICATE);
                if (authHdr != null)
                {
                    // restart SSO login as the repo has timed us out
                    restartAuthProcess(session, req, res, authHdr);
                }
                else
                {
                    // restart manual login
                    session.invalidate();
                    redirectToLoginPage(req, res);
                }
                return;
            }
            else
            {
                // we have local auth in the session and the repo session is also valid
                // this means we do not need to perform any further auth handshake
                if (logger.isDebugEnabled())
                {
                    logger.debug("Authentication not required, chaining …");
                }

               chain.doFilter(req, res); => my breakpoint stops here and then it's impossible to know what's comming next
                return;
            }
        }
        catch (ConnectorServiceException cse)
        {
            throw new PlatformRuntimeException("Incorrectly configured endpoint ID: " + this.endpoint);
        }
    }

Info : this code is part of the CVFSSOAuthenticationFilter class that is an exact copy of SSOAuthenticationFilter class used by default in Share.
It shows that the user coming from our SSO seems to be authenticated as "Authentication not required" message inside the method says.

Thank you by advance for your help

bbougon
Champ in-the-making
Champ in-the-making
Finnaly I have a solution (for an Alfresco Share / SSO authentication with Shibboleth).

First you have to set this two variables in your external-authentication.properties :

external.authentication.proxyHeader=X-Alfresco-Remote-User
external.authentication.proxyUserName

Then you have to configure your shibboleth (shibboleth2.xml) as followed :

<Host name="HOSTNAME" authType="shibboleth" applicationId="APPLICATION_ID" requireSession="true" >
   <Path name="wcs" requireSession="false" />
</Host>
The path means your shibboleth authentication won't be call when pointing to the folder wcs (ie HOSTNAME/wcs).

A brief explanation of the problem :
While we were trying to connect to Share via Shibboleth we noticed that during all the authentication process (after calling the wcs/webframework/content/metadata?user=MY_NAME) a redirection was done to shibboleth (That's the reason why we had this Json exception thrown : org.json.JSONException: A JSONObject text must begin with '{' at character 8…) and the result returned was like <html><body>… Some messages… => not the Json data awaited by Share!!!.
Actually it is the default shibboleth processing (that's why we say we do not want any Shibboleth process pointing in wcs directory).

hope this will help

loftux
Star Contributor
Star Contributor
Been watching your case in jira https://issues.alfresco.com/jira/browse/ALF-8758, and I just cant see how this works in Share.
To test this, I have in alfresco-global.properties
external.authentication.proxyUserName=
external.authentication.proxyHeader=X-Alfresco-Remote-User
external.authentication.enabled=true
external.authentication.userIdPattern=
authentication.chain=external1:external,alfrescoNtlm1:alfrescoNtlm
Then I use Firefox with Modify-Headers plugin, setting X-Alfresco-Remote-User to admin.
Browsing http://localhost:8080/alfresco I get logged in as admin
Browsing http://localhost:8080/share -Not automatically logged in, redirected to forms login.
Also tried setting the share-custom-config.xml and the alfresco endpoint <external-auth>true</external-auth>, neither true or false makes you SSO:ed in Share.

What am I missing? The case was closed, so apparently it works, but I cannot see how. The wiki article  http://wiki.alfresco.com/wiki/Alfresco_Authentication_Subsystems#External talks about the need of setting the REMOTE_USER cgi variable, but do not understand how.

For Share external SSO to work, doesn't it need to be able to pick up the user id from a Header variable and pass it on?

cling09
Champ in-the-making
Champ in-the-making
Been watching your case in jira https://issues.alfresco.com/jira/browse/ALF-8758, and I just cant see how this works in Share.
Browsing http://localhost:8080/alfresco I get logged in as admin
Browsing http://localhost:8080/share -Not automatically logged in, redirected to forms login.
What am I missing?

hello all,
i have the same problem,

http://localhost:8080/alfresco  can easy login,
but http://localhost:8080/share web site is down,

i am using alfresco SSO with cookie
http://stackoverflow.com/questions/7517122/alfresco-sso-with-cookie

anyone can help?

afaust
Legendary Innovator
Legendary Innovator
Hello,

header based external authentication does not work in Share since headers are not copied into the request to /wcs/touch by the SSOAuthenticationFilter (at least as far as 3.4.4 and 4.0.0 code that I know of is concerned). There is another topic (dealing with SiteMinder in particular) that addresses the need for a specific SSO filter which transfers the headers to the Repository in order to achieve working external authentication.

The comment above is meant "in general" with regards to external authentication - I have not yet tackled a Shibboleth authentication integration.

Regards
Axel