cancel
Showing results for 
Search instead for 
Did you mean: 

External SSO + Share

cyberjus
Champ in-the-making
Champ in-the-making
Hello All,

I am trying to authenticate Alfresco Share (community 4.2.c) against OpenAM and I am having gotten to the point where I could use some help.

I have mainly followed the instructions here: http://forums.alfresco.com/comment/84401#comment-84401
and verified that based here: http://wiki.alfresco.com/wiki/Alfresco_Authentication_Subsystems#External

It seems that the configuration of Share filters, Alfresco External auth chain, and OpenAM are correct. going to http://host/share redirects to the appropriate OpenAm login, verified header value (SsoUserHeader) is set to the user, login completes (i verified through the alfresco app that the user is created and given a home directory), and redirects back to Share. This is where I am having an issue.

I am getting a 500 error on the redirect page. Tomcat access log verifies what seems to be the correct URI
"GET /share/site-index.jsp HTTP/1.1" 500 4643

Heading to the catalina.out logs we find:

   2013-03-01 17:03:41,894  ERROR [alfresco.web.site] [http-apr-80-exec-8] org.apache.jasper.JasperException:  java.lang.NullPointerException
  java.lang.NullPointerException
   at org.apache.jsp.site_002dindex_jsp._jspService(site_002dindex_jsp.java:78)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)


Next turning to site_002dindex_jsp.java:

// retrieve user name from the session
   String userid = (String)session.getAttribute(SlingshotUserFactory.SESSION_ATTRIBUTE_KEY_USER_ID);
  
   // test user dashboard page exists?
   RequestContext context = (RequestContext)request.getAttribute(RequestContext.ATTR_REQUEST_CONTEXT);
   if (context.getObjectService().getPage("user/" + userid + "/dashboard") == null)
   {
      // no user dashboard page found! create initial dashboard for this user…
      Map<String, String> tokens = new HashMap<String, String>();
      tokens.put("userid", userid);
      FrameworkUtil.getServiceRegistry().getPresetsManager().constructPreset("user-dashboard", tokens);
   }

The offending line is the start of the If statement.

I set up a test page to try and reproduce what this page is doing. When I print out the userId and I get a "null" which leads me to believe the values are not set in the session correctly.

Then I turned to the Tomcat Manager to view the session.

Logged in through OpenAM, the only session value set was httpsession.binding.attribute (which is an OpenAM value), none of the Alfresco session values are set as when logging in to a default share instance (_alf_USER_ID, _alf_USER_OBJECT) etc.

It appears that alfresco is not setting the session values, or they are being cleared on handoff, or something.
I am hoping that I am just missing something stupid. Is there any reason Alfresco would not be setting the session values using its SSO Connector?

Any help would be much appreciated, I have been trying to get this work for a couple days now, so it is time to throw myself at the mercy of the experts.

Just for reference:
alfresco-global.properties

# Auth chain
authentication.chain=external1:external,alfrescoNtlm1:alfrescoNtlm
alfresco.authentication.allowGuestLogin=true

# SSO settings
external.authentication.enabled=true
external.authentication.defaultAdministratorUserNames=admin
external.authentication.proxyUserName=
external.authentication.proxyHeader=SsoUserHeader


Share web.xml

<?xml version='1.0' encoding='UTF-8'?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

   <display-name>Alfresco Project Slingshot</display-name>
   <description>Alfresco Project Slingshot application</description>
  
   <context-param>
      <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
      <param-value>true</param-value>
   </context-param>
  
   <!– Spring Application Context location and context class –>
   <context-param>
      <description>Spring config file location</description>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/classes/web-application-config.xml</param-value>
   </context-param>

   <filter>
      <description>Set HTTP cache Expires header 30 days forward for a mapping.</description>
      <filter-name>CacheExpiresFilter</filter-name>
      <filter-class>org.alfresco.web.scripts.servlet.StaticAssetCacheFilter</filter-class>
      <init-param>
         <description>Add an Expires Header 30 days forward</description>
         <param-name>expires</param-name>
         <param-value>30</param-value>
      </init-param>
   </filter>
  
   <filter>
      <description>MT authentication support - NOTE: does not support portlets</description>
      <filter-name>MTAuthentationFilter</filter-name>
      <filter-class>org.alfresco.web.site.servlet.MTAuthenticationFilter</filter-class>
   </filter>
  
   <filter>
      <description>Redirects view and service URLs to the dispatcher servlet.</description>
      <filter-name>UrlRewriteFilter</filter-name>
      <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
   </filter>

   <filter>
      <filter-name>OpenAMAgent</filter-name>
      <display-name>Open AM Agent</display-name>
      <description>OpenAM Tomcat Policy Agent Filter</description>
      <filter-class>com.sun.identity.agents.filter.AmAgentFilter</filter-class>
   </filter>
 
   <filter>
      <description>Share SSO authentication support filter.</description>
      <filter-name>Authentication Filter</filter-name>
      <filter-class>org.alfresco.web.site.servlet.SSOAuthenticationFilter</filter-class>
      <init-param>
         <param-name>endpoint</param-name>
         <param-value>alfresco</param-value>
      </init-param>
   </filter>
 
   <filter-mapping>
      <filter-name>OpenAMAgent</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>INCLUDE</dispatcher>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>ERROR</dispatcher>
   </filter-mapping>

   <filter-mapping>
      <filter-name>CacheExpiresFilter</filter-name>
      <url-pattern>*.jpg</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>CacheExpiresFilter</filter-name>
      <url-pattern>*.png</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>CacheExpiresFilter</filter-name>
      <url-pattern>*.gif</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>CacheExpiresFilter</filter-name>
      <url-pattern>*.css</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>CacheExpiresFilter</filter-name>
      <url-pattern>*.js</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>Authentication Filter</filter-name>
      <url-pattern>/page/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>Authentication Filter</filter-name>
      <url-pattern>/p/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>Authentication Filter</filter-name>
      <url-pattern>/proxy/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>UrlRewriteFilter</filter-name>
      <url-pattern>/proxy/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>UrlRewriteFilter</filter-name>
      <url-pattern>/service/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>UrlRewriteFilter</filter-name>
      <url-pattern>/feedservice/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>UrlRewriteFilter</filter-name>
      <url-pattern>/res/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>UrlRewriteFilter</filter-name>
      <url-pattern>/system/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>UrlRewriteFilter</filter-name>
      <url-pattern>/s/*</url-pattern>
   </filter-mapping>
  
   <filter-mapping>
      <filter-name>MTAuthentationFilter</filter-name>
      <url-pattern>/page/*</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>MTAuthentationFilter</filter-name>
      <url-pattern>/p/*</url-pattern>
   </filter-mapping>
  
   <!– Spring Context Loader listener - the name of the default global context is passed to the DispatcherServlet
        in the servlet definition below - this is to allow the NTLM filter etc. to find the single app context –>
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
  
   <servlet>
      <servlet-name>Spring Surf Dispatcher Servlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
         <param-name>contextAttribute</param-name>
         <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
   </servlet>
  
   <servlet-mapping>
      <servlet-name>Spring Surf Dispatcher Servlet</servlet-name>
      <url-pattern>/page/*</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>Spring Surf Dispatcher Servlet</servlet-name>
      <url-pattern>/p/*</url-pattern>
   </servlet-mapping>
  
   <session-config>
      <session-timeout>60</session-timeout>
   </session-config>

   <!– welcome file list precedence order is index.jsp –>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
  
   <error-page>
      <error-code>500</error-code>
      <location>/error500.jsp</location>
   </error-page>

</web-app>


share-config-custom.xml

<alfresco-config>
  
   <!– Repository Library config section –>
   <config evaluator="string-compare" condition="RepositoryLibrary" replace="true">
      <!–
         Whether the link to the Repository Library appears in the header component or not.
      –>
      <visible>true</visible>
   </config>

   <config evaluator="string-compare" condition="Remote">
      <remote>
         <endpoint>
            <id>alfresco-noauth</id>
            <name>Alfresco - unauthenticated access</name>
            <description>Access to Alfresco Repository WebScripts that do not require authentication</description>
            <connector-id>alfresco</connector-id>
            <endpoint-url>http://localhost:80/alfresco/s</endpoint-url>
            <identity>none</identity>
         </endpoint>

         <endpoint>
            <id>alfresco</id>
            <name>Alfresco - user access</name>
            <description>Access to Alfresco Repository WebScripts that require user authentication</description>
            <connector-id>alfresco</connector-id>
            <endpoint-url>http://localhost:80/alfresco/s</endpoint-url>
            <identity>user</identity>
         </endpoint>

         <endpoint>
            <id>alfresco-feed</id>
            <name>Alfresco Feed</name>
            <description>Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet</description>
            <connector-id>http</connector-id>
            <endpoint-url>http://localhost:80/alfresco/s</endpoint-url>
            <basic-auth>true</basic-auth>
            <identity>user</identity>
         </endpoint>
        
         <endpoint>
            <id>activiti-admin</id>
            <name>Activiti Admin UI - user access</name>
            <description>Access to Activiti Admin UI, that requires user authentication</description>
            <connector-id>activiti-admin-connector</connector-id>
            <endpoint-url>http://localhost:80/alfresco/activiti-admin</endpoint-url>
            <identity>user</identity>
         </endpoint>
      </remote>
   </config>
  
   <config evaluator="string-compare" condition="Remote">
      <remote>
         <keystore>
             <path>alfresco/web-extension/alfresco-system.p12</path>
             <type>pkcs12</type>
             <password>alfresco-system</password>
         </keystore>
        
         <connector>
            <id>alfrescoCookie</id>
            <name>Alfresco Connector</name>
            <description>Connects to an Alfresco instance using cookie-based authentication</description>
            <class>org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class>
      </connector>
        
         <connector>
            <id>alfrescoHeader</id>
            <name>Alfresco Connector</name>
            <description>Connects to an Alfresco instance using header and cookie-based authentication</description>
            <class>org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class>
            <userHeader>SsoUserHeader</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:80/alfresco/wcs</endpoint-url>
            <identity>user</identity>
            <external-auth>true</external-auth>
         </endpoint>
      </remote>
   </config>


</alfresco-config>



4 REPLIES 4

smcardle
Champ in-the-making
Champ in-the-making
Hi cyberjus

Two points to note :

1. The OpenAM filter should be the first filter in the filter chain.
2. In the share-config-custom.xml file you have two 
<config evaluator="string-compare" condition="Remote">…</config>
sections. For the case of SSO your first one should be commented out. The second one shown in you listing is correct.

Please change these settings and get back to me. I will try to help you resolve your issues as we are using this on about 20 environments including production now without issue.

Regards

Steve

sadagopan
Champ in-the-making
Champ in-the-making
Hi Steve,
  I have an issue in initializing the agent properties. Since Alfresco uses tomcat as Windows service it isn't able load the agent root config. any ideas ? or help me with the way you have installed the J2EE  agent

glaenen
Champ in-the-making
Champ in-the-making
Hello Cyberjus,
Hello Steve,

Did you ever solve this issue?
I'm facing the exact same problem on Alfresco 5 EE.

The share.log shows this error:

09:41:36,935 ERROR [org.alfresco.web.site] [http-apr-8080-exec-7] org.apache.jasper.JasperException: java.lang.NullPointerException
java.lang.NullPointerException
        at org.apache.jsp.site_002dindex_jsp._jspService(site_002dindex_jsp.java:78)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at com.sun.identity.agents.filter.AmAgentBaseFilter.allowRequestToContinue(AmAgentBaseFilter.java:130)
        at com.sun.identity.agents.filter.AmAgentBaseFilter.doFilter(AmAgentBaseFilter.java:80)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
        at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2378)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Thanks,
Glenn

glaenen
Champ in-the-making
Champ in-the-making
In OpenAm I was mapping the mail attribute to SsoUserHeader, after changing this from mail to cn it started working.
However this doesn't solve my problem because we want to use the mail attribute.