AnsweredAssumed Answered

Alfresco + Active Directory + Chaining

Question asked by andrea9 on Feb 27, 2009
Latest reply on Feb 27, 2009 by juan
Hi All,
this is my first post in this forum.

I am using Alfresco 3.0 Stable.
I am trying to configure Alfresco with Active Directory. I have modified the ldap-authentication.properties and renamed the ldap-authentication-context.xml.
Following I attach the two files.

ldap-authentication.properties:
#
# This properties file brings together the common options for LDAP authentication rather than editing the bean definitions
#

# How to map the user id entered by the user to taht passed through to LDAP
# - simple
#    - this must be a DN and would be something like
#      CN=%s,DC=company,DC=com
# - digest
#    - usually pass through what is entered
#      %s    
ldap.authentication.userNameFormat=%s

# The LDAP context factory to use
ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory

# The URL to connect to the LDAP server
ldap.authentication.java.naming.provider.url=ldap://10.0.0.240:389

# The authentication mechanism to use
ldap.authentication.java.naming.security.authentication=simple

# The default principal to use (only used for LDAP sync)
ldap.authentication.java.naming.security.principal=Administrator

# The password for the default principal (only used for LDAP sync)
ldap.authentication.java.naming.security.credentials=pwd

# Escape commas entered by the user at bind time
# Useful when using simple authentication and the CN is part of the DN and contains commas
ldap.authentication.escapeCommasInBind=false

# Escape commas entered by the user when setting the authenticated user
# Useful when using simple authentication and the CN is part of the DN and contains commas, and the escaped \, is
# pulled in as part of an LDAP sync
# If this option is set to true it will break the default home folder provider as space names can not contain \
ldap.authentication.escapeCommasInUid=false

ldap-authentication-context.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
   
   <!– The main configuration has moved into a properties file –>
   
    <bean name="ldapAuthenticationPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders">
            <value>true</value>
        </property> 
        <property name="locations">
            <value>classpath:alfresco/extension/ldap-authentication.properties</value>
        </property>
    </bean>
   
    <!– DAO that rejects changes - LDAP is read only at the moment. It does allow users to be deleted with out warnings from the UI. –>
   
    <bean name="authenticationDao" class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao" >
        <property name="allowDeleteUser">
            <value>true</value>
        </property>
    </bean>
  

    <!– LDAP authentication configuration –>
   
    <!–
   
    You can also use JAAS authentication for Kerberos against Active Directory or NTLM if you also require single sign on from the
    web browser. You do not have to use LDAP authentication to synchronise groups and users from an LDAP store if it supports other
    authentication routes, like Active Directory.
   
    –>
   
    <bean id="authenticationComponent"
          class="org.alfresco.repo.security.authentication.ldap.LDAPAuthenticationComponentImpl"
          parent="authenticationComponentBase">
        <property name="LDAPInitialDirContextFactory">
            <ref bean="ldapInitialDirContextFactory"/>
        </property>
        <property name="userNameFormat">
            <!–
           
            This maps between what the user types in and what is passed through to the underlying LDAP authentication.
           
            "%s" - the user id is passed through without modification.
            Used for LDAP authentication such as DIGEST-MD5, anything that is not "simple".
           
            "cn=%s,ou=London,dc=company,dc=com" - If the user types in "Joe Bloggs" the authenticate as "cn=Joe Bloggs,ou=London,dc=company,dc=com"
            Usually for simple authentication. Simple authentication always uses the DN for the user.
           
            –>
            <value>${ldap.authentication.userNameFormat}</value>
        </property>
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="personService">
            <ref bean="personService" />
        </property>
        <property name="transactionService">
            <ref bean="transactionService" />
        </property>  
        <property name="escapeCommasInBind">
            <value>${ldap.authentication.escapeCommasInBind}</value>
        </property>
        <property name="escapeCommasInUid">
            <value>${ldap.authentication.escapeCommasInUid}</value>
        </property>
    </bean>
   
    <!–
   
    This bean is used to support general LDAP authentication. It is also used to provide read only access to users and groups
    to pull them out of the LDAP reopsitory
   
    –>
   
    <bean id="ldapInitialDirContextFactory" class="org.alfresco.repo.security.authentication.ldap.LDAPInitialDirContextFactoryImpl">
        <property name="initialDirContextEnvironment">
            <map>
                <!– The LDAP provider –>
                <entry key="java.naming.factory.initial">
                    <value>${ldap.authentication.java.naming.factory.initial}</value>
                </entry>
               
                <!– The url to the LDAP server –>
                <!– Note you can use space separated urls - they will be tried in turn until one works –>
                <!– This could be used to authenticate against one or more ldap servers (you will not know which one ….) –>
                <entry key="java.naming.provider.url">
                    <value>${ldap.authentication.java.naming.provider.url}</value>
                </entry>
               
                <!– The authentication mechanism to use      –>
                <!– Some sasl authentication mechanisms may require a realm to be set –>
                <!–                java.naming.security.sasl.realm –>
                <!– The available options will depend on your LDAP provider –>
                <entry key="java.naming.security.authentication">
                    <value>${ldap.authentication.java.naming.security.authentication}</value>
                </entry>
               
                <!– The id of a user who can read group and user information –>
                <!– This does not go through the pattern substitution defined above and is used "as is" –>
                <entry key="java.naming.security.principal">
                    <value>${ldap.authentication.java.naming.security.principal}</value>
                </entry>
               
                <!– The password for the user defined above –>
                <entry key="java.naming.security.credentials">
                    <value>${ldap.authentication.java.naming.security.credentials}</value>
                </entry>
            </map>
        </property>
    </bean>
   
</beans>

Everything is ok, I can authenticate my users but only specifying the domain name, I cannot login specifying only the username. I tried to use the CN=%s,DC=company,DC=com in the ldap.authentication.userNameFormat but I cannot login if I use this user name format.
Any idea?

But the real problem apperas using the chaining authentication system.
I would like Alfresco checks the user before in Active Directory then in its user database. To do this I configured the chaining-authentication-context.xml. Following I attach the file.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
   
    <!– Chaining of both the services and components –>
   
    <bean id="authenticationService" class="org.alfresco.repo.security.authentication.ChainingAuthenticationServiceImpl">
        <property name="authenticationServices">
            <list>
                <ref bean="authenticationServiceImplLDAP"/>
            </list>
        </property>
        <property name="mutableAuthenticationService">
            <ref bean="authenticationServiceImplAlfresco"/>
        </property>
        <property name="sysAdminCache">
            <ref bean="sysAdminCache"/>
        </property>
    </bean>
   
    <bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.ChainingAuthenticationComponentImpl">
        <property name="authenticationComponents">
            <list>
                <ref bean="authenticationComponentImplLDAP"/>
            </list>
        </property>
        <property name="mutableAuthenticationComponent">
            <ref bean="authenticationComponentImplAlfresco"/>
        </property>
    </bean>
   
    <!– Alfresco Auth –>
   
    <bean id="authenticationServiceImplAlfresco" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
        <property name="authenticationDao">
            <ref bean="authenticationDaoAlfresco"/>
        </property>
        <property name="ticketComponent">
            <ref bean="ticketComponent"/>
        </property>
        <property name="authenticationComponent">
            <ref bean="authenticationComponentImplAlfresco"/>
        </property>
        <property name="sysAdminCache">
            <ref bean="sysAdminCache"/>
        </property>
    </bean>
   
    <bean id="authenticationDaoAlfresco" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
        <property name="nodeService">
            <ref bean="nodeService"/>
        </property>
        <property name="tenantService">
            <ref bean="tenantService"/>
        </property>
        <property name="dictionaryService">
            <ref bean="dictionaryService"/>
        </property>
        <property name="namespaceService">
            <ref bean="namespaceService"/>
        </property>
        <property name="searchService">
            <ref bean="admSearchService"/>
        </property>
        <property name="retryingTransactionHelper">
          <ref bean="retryingTransactionHelper"/>
        </property>
        <property name="userNamesAreCaseSensitive">
            <value>${user.name.caseSensitive}</value>
        </property>
        <property name="passwordEncoder">
            <ref bean="passwordEncoder"/>
        </property>
    </bean>
   
    <bean id="authenticationComponentImplAlfresco" class="org.alfresco.repo.security.authentication.AuthenticationComponentImpl" parent="authenticationComponentBase">
        <property name="authenticationDao">
            <ref bean="authenticationDaoAlfresco"/>
        </property>
        <property name="authenticationManager">
            <ref bean="authenticationManager"/>
        </property>
        <property name="allowGuestLogin">
            <value>false</value>
        </property>
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="personService">
            <ref bean="personService" />
        </property>
        <property name="transactionService">
            <ref bean="transactionService" />
        </property>
    </bean>
   
    <!– LDAP –>
   
    <bean id="authenticationServiceImplLDAP" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
        <property name="authenticationDao">
            <ref bean="authenticationDaoLDAP"/>
        </property>
        <property name="ticketComponent">
            <ref bean="ticketComponent"/>
        </property>
        <property name="authenticationComponent">
            <ref bean="authenticationComponentImplLDAP"/>
        </property>
        <property name="sysAdminCache">
            <ref bean="sysAdminCache"/>
        </property>
    </bean>
   
    <bean id="authenticationComponentImplLDAP" class="org.alfresco.repo.security.authentication.ldap.LDAPAuthenticationComponentImpl" parent="authenticationComponentBase">
            <property name="LDAPInitialDirContextFactory">
                <ref bean="ldapInitialDirContextFactory"/>
            </property>
            <property name="userNameFormat">
                <value>sAMAccountName=%s</value>
            </property>
    </bean>
   
    <bean id="authenticationDaoLDAP" class="org.alfresco.repo.security.authentication.ntlm.NullMutableAuthenticationDao"/>
   
</beans>

If I disable the Guest login (row 83 in the configuration file) I have the following message error:

impossible to log in as Guest
java null pointer exception

So I enabled the Guest login, but another error appears:

javax.faces.FacesException: Error calling action method of component with id loginForm:submit
caused by:
javax.faces.el.EvaluationException: Exception while invoking expression #{LoginBean.login}
caused by:
org.alfresco.error.AlfrescoRuntimeException: Not implemented

completo
avax.faces.FacesException: Error calling action method of component with id loginForm:submit
at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:72)
at javax.faces.component.UICommand.broadcast(UICommand.java:109)
at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.app.servlet.AuthenticationFilter.doFilter(AuthenticationFilter.java:94)
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:128)
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:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.faces.el.EvaluationException: Exception while invoking expression #{LoginBean.login}
at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:156)
at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:61)
… 22 more
Caused by: org.alfresco.error.AlfrescoRuntimeException: Not implemented
at org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao.loadUserByUsername(DefaultMutableAuthenticationDao.java:410)
at net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider.getUserFromBackend(DaoAuthenticationProvider.java:390)
at net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider.authenticate(DaoAuthenticationProvider.java:225)
at net.sf.acegisecurity.providers.ProviderManager.doAuthentication(ProviderManager.java:159)
at net.sf.acegisecurity.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49)
at org.alfresco.repo.security.authentication.AuthenticationComponentImpl.authenticateImpl(AuthenticationComponentImpl.java:74)
at org.alfresco.repo.security.authentication.AbstractAuthenticationComponent.authenticate(AbstractAuthenticationComponent.java:130)
at org.alfresco.repo.security.authentication.AuthenticationServiceImpl.authenticate(AuthenticationServiceImpl.java:118)
at org.alfresco.repo.security.authentication.ChainingAuthenticationServiceImpl.authenticate(ChainingAuthenticationServiceImpl.java:166)
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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:296)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:49)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
at org.alfresco.repo.audit.AuditComponentImpl.audit(AuditComponentImpl.java:275)
at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:69)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy24.authenticate(Unknown Source)
at org.alfresco.web.bean.LoginBean.login(LoginBean.java:274)
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.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:132)
… 23 more

Any idea?

Thanks for the help.

Best regards.

Outcomes