1

I want to integrate Alfresco with my current login system (which is an LDAP server). I can successfully integrate LDAP authentication in, however, I want to use an external login page and have Alfresco read a cookie to log the user in (the cookie will contain the username and a key which can be used to verify they're logged in with the LDAP server).

I looked into the example that came with the SDK, but there doesn't seem to be a way to login the user in without a password.

I was looking into the External Authentication Subsystem, and saw the CAS guide, but that seems like overkill and I'm not sure I understand everything that's going on or why all of that is needed for my situation.

After poking around in the Exernal subsystem, I saw it uses "SimpleAcceptOrRejectAllAuthenticationComponentImpl", which overrides the authentication function. In that function it authenticates a user via a "setCurrentUser" function, but that relies on the value of "accept" being set to true. I grepped through the Alfresco source, and looked in the files under WEB-INF/classes/alfresco/subsystems/Authentication/external, but I couldn't find out how the setAccept function ever got called. After some googling I found this example.

It looks like they setup a filter that logs the user in via a SimpleAcceptOrRejectAllAuthenticationComponentImpl object where they explicitly call setAccept(true). I haven't tried this yet, but their wiki says the web.xml file needs to be edited, something an Alfresco Dev said in another post wasn't needed after Alfresco v3.2 (I'm using v3.4.3). Is this the right avenue to go down?

I've heard another idea would be to write my own Authenticator subsystem, but I don't see any docs on that, and without knowing how the "setAccept" function gets called for the External subsystem, I feel like I'd be shooting in the dark.

Any thoughts on how to login a user in based on a cookie created by an external webapp (which is on the same domain - I've been able to read the cookie, I just don't know how to authenticate a user without a password)?

patorjk
  • 2,164
  • 1
  • 20
  • 30

1 Answers1

4

I figured I'd post the solution for anyone who had the same problem.

Step 1: Create a filter that will be executed when someone tries to hit one of your URLs. Once the filter is created, compile and package it in a jar, and then place that jar inside of the alfresco.war and share.war (in the location "WEB-INF/lib"). Here is a skeleton version of what the filter code will look like:

package sample.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;

public class SSOIntegrationFilter implements Filter { 
    private static final String PARAM_REMOTE_USER = "remoteUser"; 
    private static final String SESS_PARAM_REMOTE_USER = SSOIntegrationFilter.class.getName() + '.' + PARAM_REMOTE_USER; 

    @Override 
    public void init(FilterConfig arg0) throws ServletException {} 

    @Override 
    public void destroy() {} 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
        HttpServletRequest httpServletRequest = (HttpServletRequest) req; 
        String remoteUser = proprieterayUserIdValidationAndExtractionMethod(req.getParameter(PARAM_REMOTE_USER)); 
        // We've successfully authenticated the user. Remember their ID for next time. 
        if (remoteUser != null) { 
            HttpSession session = httpServletRequest.getSession(); 
            session.setAttribute(SESS_PARAM_REMOTE_USER, remoteUser); 
        } 
        chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) { 
            @Override 
            public String getRemoteUser() { 
                return (String) getSession().getAttribute(SESS_PARAM_REMOTE_USER); 
            } 
        }, res); 
    } 

    private String proprieterayUserIdValidationAndExtractionMethod(String param) { 
        return "admin"; // who to login as, replace with your cookie login code
    }
} 

Step 2: Configure the web.xml file for tomcat to recognize this filter (mine was located in /usr/share/tomcat/conf).

<filter>
    <filter-name>Demo Filter</filter-name>
    <filter-class>sample.filter.SSOIntegrationFilter</filter-class>
</filter> 

<filter-mapping>
    <filter-name>Demo Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Step 3: Make the following changes to your share-config-custom.xml file (should be located in the shared directory): http://docs.alfresco.com/3.4/index.jsp?topic=%2Fcom.alfresco.Enterprise_3_4_0.doc%2Ftasks%2Fauth-alfrescontlm-sso.html

Step 4: Update your alfresco-global.properties file with the following information:

authentication.chain=external1:external,alfrescoNtlm1:alfrescoNtlm
external.authentication.proxyUserName=X-Alfresco-Remote-User

Then start up Alfresco and try it out. Hopefully this will put you on the right track.

patorjk
  • 2,164
  • 1
  • 20
  • 30
  • Hi, I did fellow the steps mentioned here but when I'm trying to open localhost:8080\share then it is asking for password. Do I need to do any other change? please suggest. – Sam Jun 03 '13 at 04:24
  • I have one external web application. Users are authenticated through LDAP server in external web app. LDAP sync I've done with Alfresco and working fine. Now on successful authentication on external web app, I want to redirect user to Share application(response.sendRedirect(http://localhost:8080/share/page). But here login page is coming. Currently I've hard coded "admin" in the filter as you mentioned in your code. Kindly help me how to achieve this. – Sam Jun 03 '13 at 16:28
  • It's been a while since I wrote this post. My filter grew significantly - but its core is above. The proprieterayUserIdValidationAndExtractionMethod method changed to take in HttpServletRequest and HttpServletResponse objects. I read cookies off the HttpServletRequest object and also stored a session on it. To confirm validation, I passed in the cookie values to a REST call that our auth service provided. This REST call told the filter if the user was valid. So you'll want your auth service to be able to set cookies or pass data to Share that it can use to verify the user's identify. – patorjk Jun 03 '13 at 19:19
  • Just re-read what you were asking - the above filter should log you as in as admin and you shouldn't get the login screen. It's tested on the 3.4.x branch of Alfresco, though theoretically should work on the 4.x branch. I would try it with a clean install and debug from there, and if you're using 4.x, try 3.4.x to see if it's a version thing. – patorjk Jun 03 '13 at 19:27
  • Thanks a lot for your reply! I'm running on 4.x. I'll post my code here in a while. Please let me know your findings. Thanks again. – Sam Jun 03 '13 at 19:30
  • Hi patorjk, I have below entry in alfresco-global.properties under $Tomcat/Shared/Classes/ authentication.chain=external1:external,alfrescoNtlm1:alfrescoNtlm external.authentication.proxyUserName=X-Alfresco-Remote-User authentication.chain=alfrescoNtlm1:alfrescoNtlm,ldap1:ldap and exactly the same custom Filter as you have written here. After I changed \share-config-custom.xml but did not work when I trued to open localhost:8080/share, login page is coming. Please guide me. – Sam Jun 05 '13 at 00:10
  • It works for me - but I'm on 3.4.11. It's probably worth opening a new question on this, someone may be able to provide some additional insight. – patorjk Jun 05 '13 at 02:20
  • thanks @patorjk for brilliant post. I am able to login with the username returned by proprieterayUserIdValidationAndExtractionMethod() method. But for this to work, condition is user returned by mentioned function must exist in alfresco. It would be good if you provide me a way to create user before authentication takes place from your filter. – Vikash Patel Jun 21 '17 at 09:12