cancel
Showing results for 
Search instead for 
Did you mean: 

Siteminder Integration with Alfresco

mitpatoliya
Star Collaborator
Star Collaborator
I am using the Alfresco 3.4d.
What are the things require for integrating siteminder with Alfresco for using it for SSO.
Is it something we need to do with configuration files or we need to create some custom authenticator class or filter class something like that.
Can anybody suggest the steps require for that?
10 REPLIES 10

afaust
Legendary Innovator
Legendary Innovator
Hello,

we've integrated CA SiteMinder with Alfresco for one of our customers. For everything related to the Alfresco Web Client / Repository, you should be fine with the External Authentication Subsystem, which can extract any user ID token that SiteMinder adds to the request - so you only have to hassle with configuration files on this tier. For Share we had to implement a custom SSO filter that copies any SiteMinder information into the authentication request to the Repository - a rather simple implementation when you take the existing filter as a reference.

Regards
Axel

mitpatoliya
Star Collaborator
Star Collaborator
Thanks Axel for your response.
So, for explorer or repository it is just the configuration change on the alfresco side.
but if we want it with share login as well we need to create filter for that which will redirect the require for share login to our custom authenticator class and that class should validate the request with siteminder something like that right?
correct me if I am wrong at any point.
Also could you provide some coding guide line to create that filter for share?

openpj
Elite Collaborator
Elite Collaborator
Could you please provide us any other detail about this integration?

Thank you.

afaust
Legendary Innovator
Legendary Innovator
Hello,

for Share you need to implement a Siteminder aware filter and register it in web.xml - please see the default SSOAuthenticationFilter as a starting point. What you need to do is pass the Siteminder token supplied in the HTTP header to the repository, which the default filter does not do. It basically is just a matter of calling /wcs/touch while copying that one header from the front end request into the backend - if that backend request succeeds you only have to update the Share session in the same fashion the default filter does when NTLM / Kerberos SSO succeeded. This lets other components know about the successfull SSO authentication.

Regards
Axel

rhakaro
Champ in-the-making
Champ in-the-making
Hi people!

First of all, sorry for resurrect this thread. I´m becoming crazy trying to configure Share to authenticate with SiteMinder (Explorer is doing it OK).

Can you give me a bit more clues to solve my issue?

The web.xml referred in the previous post is from /share or from /alfresco?
How can I code this new Filter?

Thank you very much, best regards.


[EDITED]
Ok, I found this page:

http://basanagowdapatil.blogspot.com/2011/12/sso-authentication-filter-passing-our.html

Where this is explained very well. My problem (before test this code) is to make Siteminder execute before Share login page. Now, if I go to "http://application/alfresco", I can see the siteminder login page, but if I go to "http://application/share" I don´t, I see directly the Share login page.

rhakaro
Champ in-the-making
Champ in-the-making
Hi all again!

I just find where the jar is (alfresco-share in /share/WEB-INF/lib). Now the next step, I know I have to pass headers… but which and how??

Maybe I need to put variables in request?? Or do something in AuthenticationUtil.login?? Or in doFilter??

Thank you very much, best regards.

rhakaro
Champ in-the-making
Champ in-the-making
Hello,

I have developed the filter and it is processed before Share login page. That´s good. Now I´m passing SM_USER to AuthenticationUtil.login, but it doesn´t work. The filter code is the next:

public class SSOAuthenticationFilterShareHeader extends SSOAuthenticationFilter {

   private static Log logger = LogFactory.getLog(SSOAuthenticationFilterShareHeader.class);

   @Override
   public void doFilter(ServletRequest sreq, ServletResponse sresp,
   FilterChain chain) throws IOException, ServletException {
      
      // Get the HTTP request/response/session
      HttpServletRequest req = (HttpServletRequest) sreq;

      String userSM = req.getHeader("SM_USER");
      
      // This logger shows the user name OK
      logger.debug("Getting users: SM_USER: " + userSM);
      
      if (userSM != null) {
         AuthenticationUtil.login(req, userSM);
      }

      super.doFilter(sreq, sresp, chain);
   }
}

The problem is that I get the next error on log:

2012-05-08 13:02:44,156  ERROR [alfresco.web.site] [ajp-8009-3] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
   at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:194)
   at org.alfresco.web.site.SlingshotUserFactory.loadUser(SlingshotUserFactory.java:105)
   at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:180)
   at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
   at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:249)
   at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:182)
   at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:137)
   at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:380)
   at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:290)
   at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
   at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
   at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
   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:74)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:307)
   at com.csc.docs.sso.filter.SSOAuthenticationFilterShareHeader.doFilter(SSOAuthenticationFilterShareHeader.java:53)
   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:293)
   at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:448)
   at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:399)
   at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
   at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.extensions.surf.exception.UserFactoryException: Unable to create user - failed to retrieve user metadata:
   at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:183)
   … 35 more
java.net.SocketException: Software caused connection abort: recv failed
   at java.net.SocketInputStream.socketRead0(Native Method)
   at java.net.SocketInputStream.read(SocketInputStream.java:129)
   at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
   at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
   at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
   at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
   at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116)
   at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.readLine(MultiThreadedHttpConnectionManager.java:1413)
   at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973)
   at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735)
   at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098)
   at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
   at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
   at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
   at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
   at org.alfresco.httpclient.AbstractHttpClient.executeMethod(AbstractHttpClient.java:110)
   at org.alfresco.httpclient.AbstractHttpClient.sendRemoteRequest(AbstractHttpClient.java:86)
   at org.alfresco.httpclient.HttpClientFactory$DefaultHttpClient.sendRequest(HttpClientFactory.java:370)
   at org.alfresco.solr.client.SOLRAPIClient.getModelsDiff(SOLRAPIClient.java:1007)
   at org.alfresco.solr.tracker.CoreTracker.trackModels(CoreTracker.java:1630)
   at org.alfresco.solr.tracker.CoreTracker.trackRepository(CoreTracker.java:1134)
   at org.alfresco.solr.tracker.CoreTracker.updateIndex(CoreTracker.java:491)
   at org.alfresco.solr.tracker.CoreTrackerJob.execute(CoreTrackerJob.java:45)
   at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
   at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:563)

What could be the problem?

Thanks, regards!

rhakaro
Champ in-the-making
Champ in-the-making
Hi again,

I just have solved the exception I´d getting. Now I get another one… but this seems to be a little strange:


2012-05-10 10:31:46,357  ERROR [alfresco.web.site] [ajp-8009-1] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
   at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:194)
   at org.alfresco.web.site.SlingshotUserFactory.loadUser(SlingshotUserFactory.java:105)
   at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:180)
   at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
   at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:249)
   at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:182)
   at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:137)
   at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:380)
   at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:290)
   at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
   at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
   at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
   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:74)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.web.site.servlet.SSOAuthenticationFilter.challengeOrPassThrough(SSOAuthenticationFilter.java:619)
   at org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:338)
   at com.csc.docs.sso.filter.SSOAuthenticationFilterShareHeader.doFilter(SSOAuthenticationFilterShareHeader.java:55)
   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:293)
   at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:448)
   at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:399)
   at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
   at java.lang.Thread.run(Thread.java:662)
Caused by: org.json.JSONException: A JSONObject text must begin with '{' at character 47
   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:188)
   … 36 more

In my filter I can pass the user existing in request, and I think the authentication is working ok. But in AlfrescoUserFactory.java there is a problem resolving the json response of one webscript. I try to call directly to:

http://alfresco.server/alfresco/wcs/webframework/content/metadata?user=testuser

And it returns all the info of the user. In Firefox I can see the SiteMinder headers with lots of info, so I don´t know where can be the problem.

Any suggestion??

Thanks and best regards.

afaust
Legendary Innovator
Legendary Innovator
Hello,

this is an indication that your authentication did not work correctly. This exception occurs when the Repository responds with the HTML login page to a web script request directed at /wcs due to some problem identifying the user. Your filter should have established a session and that session should be reused for any further web script calls since only that session has been authenticated.

As I have posted before, you should take the SSOAuthenticationFilter of Share as the basis for your own filter. Handling the SM_USER token via AuthenticationUtil.login is - from my experience - the wrong way. That token should be copied into the HTTP header for a request to /wcs/touch in order to establish an authenticated session (as the SSOAuthenticationFilter does with NTLM / Kerberos information).

Regards
Axel