cancel
Showing results for 
Search instead for 
Did you mean: 

Problems writing an SSO plugin for Alfresco Share 3.3g

metadaddy
Champ in-the-making
Champ in-the-making
I am writing an OpenSSO plugin for Alfresco Share. My spec is to check for the presence and validity of an SSO token in a cookie; if the cookie is not there, or is expired, the user should login to Share in the normal way, but if the cookie is present, and contains a valid token, then the user should be automatically signed in to Share - a little different from the normal SSO use case, but it should still be doable, or so I thought…

I used the SourceSense OpenSSO plugin as a model, and got Web Client SSO working very quickly - I just ported the SourceSense code to 3.3g (a lot of classes seem to have moved about) and switched from the OpenSSO Java API to the REST API - I prefer the REST API as there are no jars to deploy.

Now, Share seems a different beast. This is the core code:


                name = openssoClient.getPrincipal(token);
                if (name != null) {
                    UserFactory userFactory = context.getServiceRegistry().getUserFactory();

                    if (userFactory.authenticate(req, name, token)) {
                        AuthenticationUtil.login(req, res, name);
                    }
                }

Now - there seem to be a couple of issues here - to use userFactory.authenticate(req, name, token), something on the other end has to be able to interpret and validate that token - presumably some component I plug in to Alfresco Web Client? If I remove the authenticate call and just do the AuthenticationUtil.login(req, res, name), things blow up later on when Share tries to get the user profile from the Web Client - it looks like it tried to get some XML, but Wireshark tells me it got an HTML login page.


SEVERE: Servlet.service() for servlet Spring Surf Dispatcher Servlet threw exception
org.json.JSONException: A JSONObject text must begin with '{' at character 45
   at org.json.JSONTokener.syntaxError(JSONTokener.java:413)
   at org.json.JSONObject.<init>(JSONObject.java:180)
   at org.json.JSONObject.<init>(JSONObject.java:420)
   at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:173)
   at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:165)
   at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
   at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:202)
   at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:175)
   at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:130)
   at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:243)
   at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:105)
   at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
   at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
   at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:67)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at com.gocetech.opensso.alfresco.OpenSSOAlfrescoShareFilter.doFilter(OpenSSOAlfrescoShareFilter.java:113)
   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:298)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
   at java.lang.Thread.run(Thread.java:637)

So - does anyone have any idea how to get this working? It looks like people have tried this in the past, but not got anywhere
1 REPLY 1

afaust
Legendary Innovator
Legendary Innovator
Using OpenSSO for authentication or any other method for that matter is totally doable if the basics are understood properly.

a) Share never ever fully authenticates a user. All that authentication plugins can do is forward credentials to the underlying repository and that repository is responsible for the authentication. (Note: NOT the web client, although it provides some of the hooks.)
b) SSO filters of Share have to work in conjunction with endpoint connectors to allow SSO and normal login behaviour depending on the entry point of the user. A SSO filter alone will not work if the endpoint connector (including its authenticator) can't retain the authenticated session on the repository.
c) Authentication filters of the repository / web client applications have to allow for the possibility of SSO and password logins. Usually the documentation/tutorials on that matter follow a SSO-only or login-only approach where both methods can not co-exist. I can not speak to the SourceSense plugin though.

What you need should be these components (based on my experience with the matter of backporting some SPNEGO fixes from 3.3 to 3.2 and enabling co-existence of SSO and login):

a) A filter for Alfresco Share that takes the SSO token, authenticates against the repository by passing it in a call to "/touch" and sets the external authentication flag in the session. Use the SSOAuthenticationFilter as a rough guideline for your implementation.
b) An authenticator for Alfresco Share endpoint connections that checks both the ticket in the connector session and the external authentication flag when determining if a user has already been authenticated. Simply extend the AlfrescoAuthenticator here. (Only this authenticator will later allow your users to both use SSO or normal login.)

You should not need to explicitly call authenticate or login on the UserFactory or the AuthenticationUtil at all for this to work.
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.