One of the main features of the Alfresco ECM System is the ability to integrate user authentication and synchronization with Microsoft Active Directory.
Unfortunately, integration is not trivial and it is error prone. While I’ll provide explanations how stuff works you can also have a look at the chapter 6 of the Professional Alfresco: Practical Solutions for Enterprise Content Management (Wrox Programmer to Programmer) [amazon.com] book or to the chapter 4 of the Alfresco 3 Enterprise Content Management Implementation
[amazon.com] book.
In this guide I’ll show you how to achieve full integration with Active Directory which includes Alfresco Explorer and Alfresco Share SSO, CIFS SSO, and Active Directory (LDAP) users and groups synchronization.
Prerequisites for this article are: working Active Directory environment, functional basic installation of Alfresco i.e. you can login into working Alfresco using the default admin/admin user. I tend to use bundled Alfresco/Tomcat zip installation since installer can be buggy from version to version and you don’t have full control. I recommend using Alfresco CE 3.2 build 2242 or later since it includes many fixes for NTLM, CIFS and LDAP merged from enterprise version. In my case Alfresco is installed on Windows 2003 EE with SP2 32bit.
Alfresco subsystems
Introduced in version 3.2 are the number of Alfresco subsystems:
- Authentication
- Synchronization
- File Servers
- IMAP
- sysAdmin
- WCM Deployment Receiver
- Third party (OpenOffice, Image Magick, etc.)
Subsystems in their nature are separate configurable modules responsible for a sub-part of the Alfresco functionality. Subsystems that we are interested in this article are the first three: authentication, synchronization and file servers. Note that configuration for subsystems is located in their respective folders as shown in the picture:
Note that LDAP synchronization is linked to LDAP authentication.
Lets get our hands dirty now.
Authentication
First thing to do to integrate user authentication with Active Directory is to configure the main authentication chain in Alfresco configuration. We do this by adding the following line in \Alfresco\tomcat\shared\classes\alfresco-global.properties:
authentication.chain=passthru1:passthru,ldap-ad1:ldap-ad
Note: ldap-ad is here in chain to support later explained user synchronization.
Now, create the file \subsystems\Authentication\passthru\passthru1\changes.properties and put the following inside:
passthru.authentication.useLocalServer=false
passthru.authentication.servers=DOMAIN\\192.168.0.1,192.168.0.1
ntlm.authentication.sso.enabled=true
alfresco.authentication.allowGuestLogin=false
ntlm.authentication.mapUnknownUserToGuest=false
passthru.authentication.authenticateCIFS=true
passthru.authentication.authenticateFTP=false
passthru.authentication.guestAccess=false
passthru.authentication.defaultAdministratorUserNames=AD_usernames
What we tell Alfresco with the above config is to use the external server for authentication, enable NTLM SSO, and put the list of usernames that should have the administrator role.
Now, edit the \Alfresco\tomcat\shared\classes\alfresco\web-extension\webscript-framework-config-custom.xml file and make sure the following is present and uncommented:
<config evaluator=”string-compare” condition=”Remote”>
<remote>
<!– SSL client certificate + trusted CAs. Optionally used to authenticate share to an external SSO system such as CAS –>
<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.connector.AlfrescoConnector</class>
</connector><endpoint>
<id>alfresco</id>
<name>Alfresco – user access</name>
<description>Access to Alfresco Repository WebScripts that require user authentication</description>
<connector-id>alfrescoCookie</connector-id>
<endpoint-url>http://localhost:8080/alfresco/wcs</endpoint-url>
<identity>user</identity>
<external-auth>true</external-auth>
</endpoint>
</remote>
</config>
Next, edit the WEB-INF\web.xml file found in share.war (hint: share.war is just a zip file with .war extension) and uncomment the following:
<filter>
<filter-name>Authentication Filter</filter-name>
<filter-class>org.alfresco.web.site.servlet.NTLMAuthenticationFilter</filter-class>
<init-param>
<param-name>endpoint</param-name>
<param-value>alfresco</param-value>
</init-param>
</filter><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>/s/*</url-pattern>
</filter-mapping>
SSO should now be fully functional for Alfresco Explorer and Alfresco Share. Lets synchronize the users and groups now.
Synchronization
For user synchronization to work we must configure Alfresco to hit the Active Directory domain controller with the appropriate LDAP queries. Queries are highly dependant of ones AD structure so the following configuration covers the scenario where:
- All groups that I want in Alfresco are members of a single group called Alfresco Groups,
- Users that I want synchronized to Alfresco are members of the above mentioned member groups.
This structure is nice if you have users in different OUs but don’t want them all to be also present in Alfresco.
So, edit the \subsystems\Authentication\ldap-ad\ldap-ad1\changes.properties file and add the following inside:
#
# LDAP Sync
#
# This flag enables use of this LDAP subsystem for authentication. It may be
# that this subsytem should only be used for synchronization, in which case
# this flag should be set to false.
ldap.authentication.active=false
ldap.authentication.java.naming.security.authentication=simple# This flag enables use of this LDAP subsystem for user and group
# synchronization. It may be that this subsytem should only be used for
# authentication, in which case this flag should be set to false.
ldap.synchronization.active=true
ldap.authentication.userNameFormat=%s
ldap.authentication.allowGuestLogin=true
ldap.authentication.java.naming.provider.url=ldap://domain.local:389# The default principal to bind with (only used for LDAP sync). This should be a UPN or DN
ldap.synchronization.java.naming.security.principal=user@domain.local# The password for the default principal (only used for LDAP sync)
ldap.synchronization.java.naming.security.credentials=YourPass# If positive, this property indicates that RFC 2696 paged results should be
# used to split query results into batches of the specified size. This
# overcomes any size limits imposed by the LDAP server.
ldap.synchronization.queryBatchSize=1000# The query to select all objects that represent the groups to import.
ldap.synchronization.groupQuery=(&(objectclass\=group)(memberOf\=cn\=Alfresco Groups,ou\=user,dc\=domain,dc\=local))# The query to select objects that represent the groups to import that have changed since a certain time.
ldap.synchronization.groupDifferentialQuery=(&(objectclass\=group)(memberOf\=cn\=Alfresco Groups,ou\=user,dc\=domain,dc\=local)(!(modifyTimestamp<\={0})))# The query to select all objects that represent the users to import.
ldap.synchronization.personQuery=(&(objectclass\=user)(|(memberOf\=CN\=Developers,OU\=user,DC\=domain,DC\=local)(memberOf\=CN\=Sales,OU\=user,DC\=domain,DC\=local))(userAccountControl\:1.2.840.113556.1.4.803\:\=512))# The query to select objects that represent the users to import that have changed since a certain time.
ldap.synchronization.personDifferentialQuery=(&(objectclass\=user)(|(memberOf\=CN\=Developers,OU\=user,DC\=domain,DC\=local)(memberOf\=CN\=Sales,OU\=user,DC\=domain,DC\=local))(userAccountControl\:1.2.840.113556.1.4.803\:\=512)(!(modifyTimestamp<\={0})))# The group search base restricts the LDAP group query to a sub section of tree on the LDAP server.
ldap.synchronization.groupSearchBase=dc\=domain,dc\=local# The user search base restricts the LDAP user query to a sub section of tree on the LDAP server.
ldap.synchronization.userSearchBase=dc\=domain,dc\=local# The name of the operational attribute recording the last update time for a group or user.
ldap.synchronization.modifyTimestampAttributeName=modifyTimestamp# The timestamp format. Unfortunately, this varies between directory servers.
ldap.synchronization.timestampFormat=yyyyMMddHHmmss’.0Z’# The attribute name on people objects found in LDAP to use as the uid in Alfresco
ldap.synchronization.userIdAttributeName=sAMAccountName# The attribute on person objects in LDAP to map to the first name property in Alfresco
ldap.synchronization.userFirstNameAttributeName=givenName# The attribute on person objects in LDAP to map to the last name property in Alfresco
ldap.synchronization.userLastNameAttributeName=sn# The attribute on person objects in LDAP to map to the email property in Alfresco
ldap.synchronization.userEmailAttributeName=mail# The attribute on person objects in LDAP to map to the organizational id property in Alfresco
ldap.synchronization.userOrganizationalIdAttributeName=company# The default home folder provider to use for people created via LDAP import
ldap.synchronization.defaultHomeFolderProvider=userHomesHomeFolderProvider# The attribute on LDAP group objects to map to the gid property in Alfrecso
ldap.synchronization.groupIdAttributeName=cn# The group type in LDAP
ldap.synchronization.groupType=group# The person type in LDAP
ldap.synchronization.personType=user# The attribute in LDAP on group objects that defines the DN for its members
ldap.synchronization.groupMemberAttributeName=membersynchronization.synchronizeChangesOnly=true
What we do above is: disable LDAP authentication and enable just LDAP synchronization, set the LDAP URL to query, credentials with read rights on LDAP, groups query, users query, and LDAP attributes to map Alfresco user’s attributes to. Note that LDAP synchronization is not instant, duration depends on number of objects to synchronize and is scheduled to run every hour (configurable in scheduled-jobs-context.xml).
CIFS
Now, the problematic part. CIFS is usually the hardest one to get it to work properly. So lets start with basic config that should work and then try to fix the eventual problems if there are any.
Edit the \subsystems\fileServers\default\default\changes.properties file and add the following inside:
filesystem.name=Alfresco
filesystem.domainMappings=DOMAIN
filesystem.domainMappings.value.DOMAIN.rangeFrom=192.168.0.0
filesystem.domainMappings.value.DOMAIN.rangeTo=192.168.0.255cifs.enabled=true
cifs.localname=HOSTNAME
cifs.domain=DOMAIN
cifs.hostannounce=true
cifs.urlfile.prefix=http://hostname:8080/alfresco/cifs.broadcast=192.168.0.255
cifs.bindto=192.168.0.123
cifs.ipv6=disabledftp.enabled=false
ftp.ipv6=disabled
nfs.enabled=false
If it doesn’t work you can try to enable only the Java socket based NetBIOS over TCP/IP. You do this by copying file-servers-context.xml to \subsystems\fileServers\default\default\custom-file-servers-context.xml and commenting out the following sections in it:
<!–
<property name=”netBIOSSMB”>
<bean class=”org.alfresco.filesys.config.NetBIOSSMBConfigBean”>
<property name=”bindTo”>
<value>${cifs.bindto}</value>
</property>
<property name=”sessionPort”>
<value>${cifs.netBIOSSMB.sessionPort}</value>
</property>
<property name=”namePort”>
<value>${cifs.netBIOSSMB.namePort}</value>
</property>
<property name=”datagramPort”>
<value>${cifs.netBIOSSMB.datagramPort}</value>
</property>
<property name=”platforms”>
<value>linux,solaris,macosx</value>
</property>
</bean>
</property>
–>
<!– Use Win32 NetBIOS interface on Windows –>
<!–
<property name=”win32NetBIOS”>
<bean class=”org.alfresco.filesys.config.Win32NetBIOSConfigBean” />
</property>
<property name=”win32HostAnnouncerEnabled”>
<value>${cifs.hostannounce}</value>
</property>
<property name=”win32HostAnnounceInterval”>
<value>5</value>
</property>
–>
Make sure the following property is setup like this:
<!– Use Java socket based NetBIOS over TCP/IP and native SMB on linux –>
<property name=”tcpipSMB”>
<bean class=”org.alfresco.filesys.config.TcpipSMBConfigBean”>
<!–
Can be mapped to non-privileged ports, then use firewall rules to forward requests from the standard
ports
–>
<property name=”port”>
<value>${cifs.tcpipSMB.port}</value>
</property>
<property name=”ipv6Enabled”>
<value>${cifs.ipv6.enabled}</value>
</property>
</bean>
</property>
You must also disable the native SMB over TCP/IP by editing th following registry key:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters]
“SMBDeviceEnabled”=dword:00000000
You can also try to disable File and Printer sharing in the network interface’s properties dialog.
Conclusion
As you can see Alfresco integration with Active Directory can be tricky but benefits you get are definitely worth the trouble. If you have any questions feel free to ask them in comments. Feedback is highly appreciated.
October 8th, 2009
Ivan Pleština
Posted in
Tags: 

Ivan, thx for the great work you done, however user syncing from W2k ad don’t work! I followed your instructions but getting these message in log:
ERROR [org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer] Synchronization aborted due to error
org.alfresco.error.AlfrescoRuntimeException: 03270000 User and group import failed
…
Caused by: javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name ‘dc=domain,dc=local’
…
WARN [org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer] Failed initial synchronize with user registries
org.alfresco.error.AlfrescoRuntimeException: 03270000 User and group import failed
What the heck am I doing wrong?
I’m struggling with the “java.text.ParseException: Unparseable date: “20100129023330.0Z” issue as well.
Does anyone have a fix/cause of this?
I solved the problem. My format string had backticks (`), instead of apostrophes (‘).
Sorry for the delay in answering. Apparently I stopped getting notifications about new comments…
Depends in which security zone is your site. It should log you in automatically if it is placed in Intranet zone. Otherwise, it pops up login window. There is a setting in IE when you click “Custom Level…” at the bottom of the list that controls automatic login in all zones. Other tab will log you in automatically because you’ve already logged in on first tab.
Sorry for the delay in answering. Apparently I stopped getting notifications about new comments…
Um, have you changed dc=domain,dc=local you match your environment? Other problem could be if you are trying to get results from multiple domains…
Hello Ivan,
we have tested this with a 3.2 Community version and it is working fine, but withe the 3.2r Enterprise version, gives an error recovering the groups and users from the AD:
04260000 user and group import failed
Do you know which can be the trouble with this?
Javier,
Can you post entire exception?
Thank you for your fast reply, this is the exception:
09:37:26,521 User:System INFO [security.sync.ChainingUserRegistrySynchronizer]
Synchronizing users and groups with user registry ‘ldap1′
09:37:26,537 User:System INFO [security.sync.ChainingUserRegistrySynchronizer]
Retrieving all groups from user registry ‘ldap1′
09:37:26,599 User:System ERROR [security.sync.ChainingUserRegistrySynchronizer]
Synchronization aborted due to error
org.alfresco.error.AlfrescoRuntimeException: 04270000 User and group import fail
ed
at org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.processQuery(LD
APUserRegistry.java:895)
at org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.getGroups(LDAPU
serRegistry.java:623)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.sync
WithPlugin(ChainingUserRegistrySynchronizer.java:545)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.sync
hronize(ChainingUserRegistrySynchronizer.java:412)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer$7.do
Work(ChainingUserRegistrySynchronizer.java:1251)
at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(Au
thenticationUtil.java:514)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onBo
otstrap(ChainingUserRegistrySynchronizer.java:1245)
at org.alfresco.util.AbstractLifecycleBean.onApplicationEvent(AbstractLi
fecycleBean.java:62)
at org.springframework.context.event.SimpleApplicationEventMulticaster$1
.run(SimpleApplicationEventMulticaster.java:77)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecut
or.java:49)
at org.springframework.context.event.SimpleApplicationEventMulticaster.m
ulticastEvent(SimpleApplicationEventMulticaster.java:75)
at org.springframework.context.support.AbstractApplicationContext.publis
hEvent(AbstractApplicationContext.java:246)
at org.springframework.context.support.AbstractApplicationContext.finish
Refresh(AbstractApplicationContext.java:617)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:355)
at org.alfresco.repo.management.subsystems.ChildApplicationContextFactor
y$ApplicationContextState.start(ChildApplicationContextFactory.java:637)
at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.st
art(AbstractPropertyBackedBean.java:454)
at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.on
ApplicationEvent(AbstractPropertyBackedBean.java:377)
at org.springframework.context.event.SimpleApplicationEventMulticaster$1
.run(SimpleApplicationEventMulticaster.java:77)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecut
or.java:49)
at org.springframework.context.event.SimpleApplicationEventMulticaster.m
ulticastEvent(SimpleApplicationEventMulticaster.java:75)
at org.springframework.context.support.AbstractApplicationContext.publis
hEvent(AbstractApplicationContext.java:246)
at org.springframework.context.support.AbstractApplicationContext.finish
Refresh(AbstractApplicationContext.java:617)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:355)
at org.springframework.web.context.ContextLoader.createWebApplicationCon
text(ContextLoader.java:246)
at org.springframework.web.context.ContextLoader.initWebApplicationConte
xt(ContextLoader.java:189)
at org.springframework.web.context.ContextLoaderListener.contextInitiali
zed(ContextLoaderListener.java:49)
at org.alfresco.web.app.ContextLoaderListener.contextInitialized(Context
LoaderListener.java:69)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
t.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
342)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:77
1)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.ja
va:627)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.j
ava:553)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488
)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
eSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443
)
at org.apache.catalina.core.StandardService.start(StandardService.java:5
16)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710
)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: javax.naming.PartialResultException: [LDAP: error code 10 - 0000202B:
RefErr: DSID-031006E0, data 0, 1 access points
ref 1: 'abcfotografico.abc'
]; remaining name ‘OU=TMI,DC=abcfotografico,DC=abc’
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2877)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2794)
at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1826)
at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1749)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirCon
text.java:368)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCom
positeDirContext.java:338)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCom
positeDirContext.java:321)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.jav
a:248)
at org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.processQuery(LD
APUserRegistry.java:883)
… 50 more
09:37:26,662 User:System WARN [security.sync.ChainingUserRegistrySynchronizer]
Failed initial synchronize with user registries
org.alfresco.error.AlfrescoRuntimeException: 04270000 User and group import fail
ed
at org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.processQuery(LD
APUserRegistry.java:895)
at org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.getGroups(LDAPU
serRegistry.java:623)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.sync
WithPlugin(ChainingUserRegistrySynchronizer.java:545)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.sync
hronize(ChainingUserRegistrySynchronizer.java:412)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer$7.do
Work(ChainingUserRegistrySynchronizer.java:1251)
at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(Au
thenticationUtil.java:514)
at org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.onBo
otstrap(ChainingUserRegistrySynchronizer.java:1245)
at org.alfresco.util.AbstractLifecycleBean.onApplicationEvent(AbstractLi
fecycleBean.java:62)
at org.springframework.context.event.SimpleApplicationEventMulticaster$1
.run(SimpleApplicationEventMulticaster.java:77)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecut
or.java:49)
at org.springframework.context.event.SimpleApplicationEventMulticaster.m
ulticastEvent(SimpleApplicationEventMulticaster.java:75)
at org.springframework.context.support.AbstractApplicationContext.publis
hEvent(AbstractApplicationContext.java:246)
at org.springframework.context.support.AbstractApplicationContext.finish
Refresh(AbstractApplicationContext.java:617)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:355)
at org.alfresco.repo.management.subsystems.ChildApplicationContextFactor
y$ApplicationContextState.start(ChildApplicationContextFactory.java:637)
at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.st
art(AbstractPropertyBackedBean.java:454)
at org.alfresco.repo.management.subsystems.AbstractPropertyBackedBean.on
ApplicationEvent(AbstractPropertyBackedBean.java:377)
at org.springframework.context.event.SimpleApplicationEventMulticaster$1
.run(SimpleApplicationEventMulticaster.java:77)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecut
or.java:49)
at org.springframework.context.event.SimpleApplicationEventMulticaster.m
ulticastEvent(SimpleApplicationEventMulticaster.java:75)
at org.springframework.context.support.AbstractApplicationContext.publis
hEvent(AbstractApplicationContext.java:246)
at org.springframework.context.support.AbstractApplicationContext.finish
Refresh(AbstractApplicationContext.java:617)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:355)
at org.springframework.web.context.ContextLoader.createWebApplicationCon
text(ContextLoader.java:246)
at org.springframework.web.context.ContextLoader.initWebApplicationConte
xt(ContextLoader.java:189)
at org.springframework.web.context.ContextLoaderListener.contextInitiali
zed(ContextLoaderListener.java:49)
at org.alfresco.web.app.ContextLoaderListener.contextInitialized(Context
LoaderListener.java:69)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
t.java:3843)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
342)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:77
1)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.ja
va:627)
at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.j
ava:553)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488
)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
eSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443
)
at org.apache.catalina.core.StandardService.start(StandardService.java:5
16)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710
)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: javax.naming.PartialResultException: [LDAP: error code 10 - 0000202B:
RefErr: DSID-031006E0, data 0, 1 access points
ref 1: 'abcfotografico.abc'
]; remaining name ‘OU=TMI,DC=abcfotografico,DC=abc’
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2877)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2794)
at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1826)
at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1749)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirCon
text.java:368)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCom
positeDirContext.java:338)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCom
positeDirContext.java:321)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.jav
a:248)
at org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.processQuery(LD
APUserRegistry.java:883)
… 50 more
Hello again, I have make it work, it is an issue in Alfresco Enterprise 3.2r SP1:
http://issues.alfresco.com/jira/browse/ALF-2796?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel
We have an additional error now, when using CIFS with AD users:
11:31:45,558 DEBUG [smb.protocol.auth] Using Write transaction
11:31:45,558 DEBUG [smb.protocol.auth] No PassthruDetails for WNB1
11:31:45,590 ERROR [smb.protocol.auth] Passthru error getting challenge
java.lang.NullPointerException
at org.alfresco.jlan.util.IPAddress.asInteger(IPAddress.java:137)
at org.alfresco.jlan.server.auth.CifsAuthenticator.mapClientAddressToDom
ain(CifsAuthenticator.java:958)
at org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator.getAuthConte
xt(PassthruCifsAuthenticator.java:389)
at org.alfresco.jlan.server.auth.CifsAuthenticator.generateNegotiateResp
onse(CifsAuthenticator.java:378)
at org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator.generateNego
tiateResponse(PassthruCifsAuthenticator.java:448)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory
$1.invoke(ChainingSubsystemProxyFactory.java:109)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
cAopProxy.java:204)
at $Proxy151.generateNegotiateResponse(Unknown Source)
at org.alfresco.jlan.smb.server.SMBSrvSession.procSMBNegotiate(SMBSrvSes
sion.java:1199)
at org.alfresco.jlan.smb.server.SMBSrvSession.processPacket(SMBSrvSessio
n.java:1452)
at org.alfresco.jlan.smb.server.CIFSThreadRequest.runRequest(CIFSThreadR
equest.java:57)
at org.alfresco.jlan.server.thread.ThreadRequestPool$ThreadWorker.run(Th
readRequestPool.java:141)
at java.lang.Thread.run(Thread.java:619)
11:31:45,590 DEBUG [smb.protocol.auth] Using Write transaction
11:31:45,590 DEBUG [smb.protocol.auth] No PassthruDetails for WNB2
11:32:01,871 ERROR [smb.protocol.auth] Passthru error getting challenge
java.lang.NullPointerException
at org.alfresco.jlan.util.IPAddress.asInteger(IPAddress.java:137)
at org.alfresco.jlan.server.auth.CifsAuthenticator.mapClientAddressToDom
ain(CifsAuthenticator.java:958)
at org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator.getAuthConte
xt(PassthruCifsAuthenticator.java:389)
at org.alfresco.jlan.server.auth.CifsAuthenticator.generateNegotiateResp
onse(CifsAuthenticator.java:378)
at org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator.generateNego
tiateResponse(PassthruCifsAuthenticator.java:448)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory
$1.invoke(ChainingSubsystemProxyFactory.java:109)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
cAopProxy.java:204)
at $Proxy151.generateNegotiateResponse(Unknown Source)
at org.alfresco.jlan.smb.server.SMBSrvSession.procSMBNegotiate(SMBSrvSes
sion.java:1199)
at org.alfresco.jlan.smb.server.SMBSrvSession.processPacket(SMBSrvSessio
n.java:1452)
at org.alfresco.jlan.smb.server.CIFSThreadRequest.runRequest(CIFSThreadR
equest.java:57)
at org.alfresco.jlan.server.thread.ThreadRequestPool$ThreadWorker.run(Th
readRequestPool.java:141)
at java.lang.Thread.run(Thread.java:619)
Thank you again
It seems that Alfresco can’t map client IP address to a domain name. You could try to comment out domain mappings from CIFS configuration.
Hi Ivan,
Thanks alot for the post. I’m having trouble getting this working with Community 3.3. I have followed your instructions as closely as I can, but I am currently stuck with this error:
ERROR [org.alfresco.fileserver] CIFS server configuration error, Error creating bean with name ‘authenticationComponent’ defined in file [C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\alfresco\subsystems\Authentication\ldap-ad\..\common-ldap-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type ‘java.lang.String’ to required type ‘boolean’ for property ‘active’; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [${ldap.authentication.active}]
The error seems to repeat itself down the log file. Perhaps it is somthing I should be posting to Alfresco forum…?
Cheers!
Tim.
Article is written for v3.2r2 so it probably needs some minor modifications. On the other hand your error seems to be that ldap.authentication.active is not ‘true’ or ‘false’. Perhaps you’ve got a typo there or something?
Thanks for the reply, Ivan.
I can report that there is no typo in the “changes.properties” file in the authentication/ldap-ad/ldap-ad1 directory.
Your comments therefore led me to question whether it was looking to this file for this information – after playing around it seems that it isn’t. I will take a closer look at why that is the case, but any suggestions off the top of your head would be very welcome? For example, are there any other files we need to copy into the “subsystem” directory structure in the other than the “changes.properties” files? Or any critical configuration settings required to make alfresco look in there which I may have missed?
Thanks again,
Tim.
It’s interesting that error is reported by CIFS. Ldap authentication is not supported for CIFS. What does your authentication chain look like? Also can you disable CIFS and then try?
Authentication chain is as above:
authentication.chain=passthru1:passthru,ldapad1:ldap-ad
Disabled CIFS -> no longer getting that error. Looks to have fixed that problem!
Remaining LDAP query problem, same as Marc above (April 27, 2010 @ 17:16). The error is:
Caused by: javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name ‘DC=kjrg,DC=local’
I am pretty sure the query string is right, since I’ve copied it straight out of my ADSI Edit; also not going over multiple domains. Been trying to google an answer to this, hard to find – any thoughts?
My code:
# The query to select all objects that represent the groups to import.
ldap.synchronization.groupQuery=(&(objectclass\=group)(memberOf\=cn\=Alfresco Groups,ou\=Security Groups,ou\=MyBusiness,dc\=kjrg,dc\=local))
# The query to select objects that represent the groups to import that have changed since a certain time.
ldap.synchronization.groupDifferentialQuery=(&(objectclass\=group)(memberOf\=cn\=Alfresco Groups,ou\=Security Groups,ou\=MyBusiness,dc\=kjrg,dc\=local)(!(modifyTimestamp<\={0})))
# The query to select all objects that represent the users to import.
ldap.synchronization.personQuery=(&(objectclass\=user)(memberOf\=CN\=SBSUsers,OU\=Users,OU\=MyBusiness,DC\=kjrg,DC\=local)(userAccountControl\:1.2.840.113556.1.4.803\:\=512))
# The query to select objects that represent the users to import that have changed since a certain time.
ldap.synchronization.personDifferentialQuery=(&(objectclass\=user)(memberOf\=CN\=SBSUsers,OU\=Users,OU\=MyBusiness,DC\=kjrg,DC\=local)(userAccountControl\:1.2.840.113556.1.4.803\:\=512)(!(modifyTimestamp<\={0})))
# The group search base restricts the LDAP group query to a sub section of tree on the LDAP server.
ldap.synchronization.groupSearchBase=dc\=kjrg,dc\=local
# The user search base restricts the LDAP user query to a sub section of tree on the LDAP server.
ldap.synchronization.userSearchBase=dc\=kjrg,dc\=local
Tim.
Sorry…
Found Javier’s answer above. Solution is to edit the common-ldap-context.xml file to include extra entry key…
Thanks again Ivan, it’s an exceptionally helpful post!
Tim.
Hello again,
I seem to have it working (can login with AD credentials). The question I now have is: can login be automatic?
Of course. Authentication section of the article describes all required settings. IE should log you in automatically if the site is in Intranet zone (with default settings). Firefox and Mozilla also support the use of NTLM but you need to add the URI to the Alfresco site that you want to access to network.automatic-ntlm-auth.trusted-uris option (available through writing about:config in the URL field) to allow the browser to use your current credentials for login purposes.
Thanks again for getting back to me, Ivan. I have combed through the post once or twice more (and the web a few times) – just been stuck for the last 5 or so days. What’s going on is:
* Tomcat console tells me AD sync has worked
* I can confirm the sync has worked, because in Firefox I can login to Alfresco Explorer (though not Share) with the credentials via the faces.jsp login page, and see the profile info synced.
* However if I jump into IE it tries to log me in automatically and fails, spitting the Windows 7 credentials dialog. When I enter the password, it always fails – with the Tomcat console reporting the failure.
* There are obviously other issues with Share, which does not login nor report authentication failures (or attempt to login automatically).
Given the success of the sync, I assume my LDAP queries are accurate. The thought I had was that perhaps the “ldap.authentication.userNameFormat=%s” was returning an incoherent string for whatever reason. I’ve tried many different permutations of this (including full LDAP query syntax) with no luck.
Any advice would be very highly valued.
Cheers,
Tim.
Managed to get Alfresco Explorer working, thanks to the following:
http://forums.alfresco.com/en/viewtopic.php?f=9&t=16794
I needed to make the group policy setting for NTLM authentication recommended in this post.
Still cannot get Share going – am continuing to work through all the information on the web for something I’ve missed.
Ivan, I appreciate your documentation too. Thanks. I’m running CE3.3 and so far this is the best explanation I’ve seen.
In the examples you’ve provided above it would be helpful if I knew which settings needed to be set specifically for my domain. It’s obvious that some of the entries must be changed (IP addresses, etc.) but I’m uncertain about some of the others.
Can you give us (newbies) a little more info on the settings that are site-specific? Thanks in advance!
Hi Curtis,
thanks for feedback.
I’m preparing a new guide for version 3.3g and I’ll try to highlight those custom sections. New article will be more up to date and also simplify some stuff and have some corrections.
As for now, I can give you a quick list:
passthru.authentication.servers=DOMAIN\\192.168.0.1,192.168.0.1
passthru.authentication.defaultAdministratorUserNames=AD_usernames
ldap.authentication.java.naming.provider.url=ldap://domain.local:389
ldap.synchronization.java.naming.security.principal=user@domain.local
ldap.synchronization.java.naming.security.credentials=YourPass
ldap.synchronization.groupQuery=
ldap.synchronization.groupDifferentialQuery=
ldap.synchronization.personQuery=
ldap.synchronization.personDifferentialQuery=
ldap.synchronization.groupSearchBase=dc\=domain,dc\=local
ldap.synchronization.userSearchBase=dc\=domain,dc\=local
filesystem.domainMappings=DOMAIN
filesystem.domainMappings.value.DOMAIN.rangeFrom=192.168.0.0
filesystem.domainMappings.value.DOMAIN.rangeTo=192.168.0.255
cifs.localname=HOSTNAME
cifs.domain=DOMAIN
cifs.urlfile.prefix=http://hostname:8080/alfresco/
cifs.broadcast=192.168.0.255
cifs.bindto=192.168.0.123
I hope this helps!
[...] last article on Alfresco integration with Active Directory brought up a lot of interest and what’s the most important positive feedback. That article is [...]