cancel
Showing results for 
Search instead for 
Did you mean: 

Since Kerberos SSO can't chain, trying Apache mod_auth_kerb

xkahn
Champ in-the-making
Champ in-the-making
So it looks like Alfresco can't chain Kerberos with SSO.  ( http://forums.alfresco.com/en/viewtopic.php?f=3&t=24149 )  So I'm trying to use external auth with Apache configured to authenticate users via Kerberos and mod_jk to forward the request.

Apache puts the user name in the "REMOTE_USER" header.  I've edited Alfresco's web.xml and replaced the header x-user with REMOTE_USER.  But still I don't see anything.  My setup looks like this:

web.xml:

      <init-param>
         <param-name>httpServletRequestAuthHeaderName</param-name>
         <param-value>REMOTE_USER</param-value>
      </init-param>

alfresco-global.properties:

authentication.chain=external1:external
external.authentication.enabled=true
external.authentication.userIdPattern=([A-Za-z0-9]*)@.*

I haven't been able to see any debugging messages for the external auth method.  My logs look like this (after several log in attempts; apache credentials were supplied and passed):
alfresco.log:
15:56:21,609 INFO  [org.alfresco.repo.management.subsystems.ChildApplicationContextFactory] Starting 'Synchronization' subsystem, ID: [Synchronization, default]
15:56:21,629 INFO  [org.alfresco.config.JndiPropertyPlaceholderConfigurer] Loading properties file from class path resource [alfresco/alfresco-shared.properties]
15:56:21,726 INFO  [org.alfresco.repo.management.subsystems.ChildApplicationContextFactory] Starting 'Authentication' subsystem, ID: [Authentication, managed, external1]
15:56:21,747 INFO  [org.alfresco.config.JndiPropertyPlaceholderConfigurer] Loading properties file from class path resource [alfresco/alfresco-shared.properties]
15:56:21,919 INFO  [org.alfresco.repo.management.subsystems.ChildApplicationContextFactory] Startup of 'Authentication' subsystem, ID: [Authentication, managed, external1] complete
15:56:21,959 INFO  [org.alfresco.repo.management.subsystems.ChildApplicationContextFactory] Startup of 'Synchronization' subsystem, ID: [Synchronization, default] complete
15:56:22,175 INFO  [org.alfresco.service.descriptor.DescriptorService] Alfresco JVM - v1.6.0_17-b04; maximum heap size 618.688MB
15:56:22,176 INFO  [org.alfresco.service.descriptor.DescriptorService] Alfresco started (Community): Current version 3.2.0 (r2 2440) schema 3300 - Originally installed version 3.2.0 (r2 2440) schema 3300
15:56:23,146 INFO  [org.alfresco.module.vti.VtiServer] Vti server started successfully on port: 7070
15:56:45,229 INFO  [org.alfresco.web.site.FrameworkHelper] Successfully Initialized Web Framework
15:56:45,624 INFO  [org.alfresco.config.JBossEnabledWebApplicationContext] Refreshing org.alfresco.config.JBossEnabledWebApplicationContext@60d45375: display name [Root WebApplicationContext]; startup date [Thu Jan 07 15:56:45 EST 2010]; root of context hierarchy
15:56:45,788 INFO  [org.alfresco.config.JBossEnabledWebApplicationContext] Bean factory for application context [org.alfresco.config.JBossEnabledWebApplicationContext@60d45375]: org.springframework.beans.factory.support.DefaultListableBeanFactory@4ce7372b
15:56:47,378 INFO  [org.alfresco.web.scripts.DeclarativeRegistry] Registered 22 Web Scripts (+0 failed), 24 URLs
15:56:47,387 INFO  [org.alfresco.web.scripts.AbstractRuntimeContainer] Initialised Presentation Web Script Container (in 168.698ms)
15:56:47,528 INFO  [org.alfresco.web.scripts.DeclarativeRegistry] Registered 40 Web Scripts (+0 failed), 42 URLs
15:56:47,536 INFO  [org.alfresco.web.scripts.AbstractRuntimeContainer] Initialised WebFramework Web Script Container (in 146.136ms)
15:56:47,801 INFO  [org.alfresco.web.site.FrameworkHelper] Successfully Initialized Web Framework

My log4j.properties file has:

log4j.logger.org.alfresco.repo.security.authentication=debug
log4j.logger.org.alfresco.web.app.servlet=debug
log4j.logger.org.alfresco.repo.webdav.auth=debug
log4j.logger.org.alfresco.web.app.servlet.HTTPRequestAuthenticationFilter=debug
log4j.logger.org.alfresco.repo.webdav.auth.HTTPRequestAuthenticationFilter=debug

Those were my attempts to get SOME kind of logging out.

I see lots of logging messages in projects/web-client/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java but nothing is ever printed.  What am I missing?
4 REPLIES 4

dward
Champ on-the-rise
Champ on-the-rise
See http://wiki.alfresco.com/wiki/Alfresco_With_mod_auth_cas for how to set up tomcat, mod_jk and the external authentication subsystem. Obviously you won't need mod_auth_cas, but you can use the same configuration to ensure that the REMOTE_USER CGI variable is propagated to tomcat.

xkahn
Champ in-the-making
Champ in-the-making
See http://wiki.alfresco.com/wiki/Alfresco_With_mod_auth_cas for how to set up tomcat, mod_jk and the external authentication subsystem. Obviously you won't need mod_auth_cas, but you can use the same configuration to ensure that the REMOTE_USER CGI variable is propagated to tomcat.

This still isn't working, but thank you for the pointer!  I'd read through that document before, but checking to see if REMOTE_USER was propagated was very helpful hint. 

Reading through HTTPRequestAuthenticationFilter.java, it looks like environment variables aren't being set; it wants REMOTE_USER (or x-user) to come through the HTTP headers.  I've adjusted my Apache config to look like this:


JkWorkersFile "/etc/tomcat5/jk-workers.properties"
JkLogFile "/var/log/tomcat5/mod_jk.log"

JkLogLevel debug

JkMount /alfresco ajp13
JkMount /alfresco/* ajp13

<Location /alfresco>
# Turn on SSL
  SSLRequireSSL
  SSLVerifyClient optional
  SSLCACertificatePath /etc/pki/tls/certs/
  SSLOptions +StdEnvVars +ExportCertData

# Force Kerberos Authentication, prefer SSO, but allow Basic Auth too
  AuthType Kerberos
  AuthName "Kerberos Login"
  KrbMethodNegotiate On
  KrbMethodK5Passwd On
  KrbAuthRealms MYCOMPANY.COM
  Krb5KeyTab /etc/krb5.keytab
  require valid-user

# Grab the REMOTE_USER apache environment variable for HTTP forwarding
  RewriteEngine On
  RewriteCond %{LA-U:REMOTE_USER} ([-a-zA-z0-9\.]+)[@]*.*
  RewriteRule . - [E=RU:%1]

# Set the REMOTE_USER and x-user to the authenticated username
  RequestHeader set REMOTE_USER %{RU}e
  RequestHeader set x-user %{RU}e

</Location>

To test everything, I restored Alfresco Kerberos non-SSO authentication.  I then destroyed my Kerberos ticket.  Browsing to my Alfresco install, I see a browser login box.  My Kerberos authentication is accepted.  Alfresco then displays a login box.  Entering my same credentials allows me to log in.  Viewing Administration Console -> System Information -> HTTP Request Headers shows:


host   alfresco.mycompany.com
connection   keep-alive
user-agent   Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/532.8 (KHTML, like Gecko) Chrome/4.0.285.0 Safari/532.8
referer   https://alfreso-xkahn.lab.eng.bos.redhat.com/alfresco/faces/jsp/dialog/container.jsp
content-length   385
Cache-Control   max-age=0
authorization   Basic Secret
Origin   https://alfresco.mycompany.com
content-type   application/x-www-form-urlencoded
accept   application/xml,application/xhtml+xml,text/html; q=0.9,text/plain; q=0.8,image/png,*/*; q=0.5
Accept-Encoding   gzip,deflate
cookie   _alfTest=_alfTest; JSESSIONID=secret; alfUser=bkahn
Accept-Language   en-US,en; q=0.8
Accept-Charset   ISO-8859-1,utf-8; q=0.7,*; q=0.3
REMOTE_USER   bkahn
x-user   bkahn

So, as near as I can tell, the set up works.

Switching back to external authentication, I'm still seeing no logs.  I have removed the userIdPattern pattern since Apache is handling that filter now, so my set up is:

alfresco-global.properties:
    authentication.chain=external1:external
    external.authentication.enabled=true

No word from the logs.  I think I'm still missing something.  I've tried setting the header: X-Alfresco-Remote-User which DOES seem to do something, but tries to use bkahn@MYCOMPANY.COM as the username even when I re-enable the userIdPattern. 

I need another hint!

steffen
Champ in-the-making
Champ in-the-making
Hi xkahn,

Apache puts the user name in the "REMOTE_USER" header. I've edited Alfresco's web.xml and replaced the header x-user with REMOTE_USER. But still I don't see anything.

did you remember to change the filter-class attribute in the web.xml? It should look like this:


  <filter>
     <filter-name>Authentication Filter</filter-name>
     <filter-class>org.alfresco.web.app.servlet.HTTPRequestAuthenticationFilter</filter-class>

     <!– Name of HTTP header containing UserID. –>
     <init-param>
        <param-name>httpServletRequestAuthHeaderName</param-name>
        <param-value>REMOTE_USER</param-value>
     </init-param>

  </filter>

this would also explain why no logging occurs. Otherwise I'd suggest you to remote debug Alfrescos AuthenticationFilter(s)

org.alfresco.web.app.servlet.HTTPRequestAuthenticationFilter

and

org.alfresco.web.app.servlet.AuthenticationFilter

to find out what's going wrong

ALF remote debug howto: http://forums.alfresco.com/en/viewtopic.php?t=1914

HTH

steffen

xkahn
Champ in-the-making
Champ in-the-making
Hmm…  Okay, I restarted my web browser and Apache and Tomcat.  And now things seem to be working for the most part. 

(Restoring a browser session sometimes displays an error message:
15:43:00,615 ERROR [org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/alfresco].[jsp]] Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
   at org.alfresco.web.bean.dialog.DialogManager.getTitle(DialogManager.java:208)
   at org.apache.jsp.jsp.dialog.container_jsp._jspService(container_jsp.java:176)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
   at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
   at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
   at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
   at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
   at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
   at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:419)
   at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:211)
   at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
   at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132)
   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.alfresco.web.app.servlet.AuthenticationFilter.doFilter(AuthenticationFilter.java:110)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:122)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy192.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:88)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:74)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:122)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy192.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:88)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
   at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:200)
   at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
   at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:775)
   at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:704)
   at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:897)
   at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
   at java.lang.Thread.run(Thread.java:619)
15:43:00,617 ERROR [org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/alfresco].[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
   at org.alfresco.web.bean.dialog.DialogManager.getTitle(DialogManager.java:208)
   at org.apache.jsp.jsp.dialog.container_jsp._jspService(container_jsp.java:176)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
   at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
   at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
   at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
   at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
   at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
   at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:419)
   at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:211)
   at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
   at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132)
   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.alfresco.web.app.servlet.AuthenticationFilter.doFilter(AuthenticationFilter.java:110)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:122)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy192.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:88)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:74)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:122)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy192.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:88)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
   at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:200)
   at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
   at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:775)
   at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:704)
   at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:897)
   at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
   at java.lang.Thread.run(Thread.java:619)

But not always, I guess.

The next problem is that I seem to be seeing my kerberos realm in my username.  So my username is bkahn@MYCOMPANY.COM  instead of bkahn.  I can't figure out where it is getting that name. 

Headers have:
authorization   Negotiate ReallyLongSecretThatLooksLikeGibberishButLikelyEncodesMyPrincipalName
REMOTE_USER   bkahn
x-user   bkahn
X-Alfresco-Remote-User   bkahn

So is Alfresco getting the username details out of the cookie?  How do I filter the name?