Integration with Microsoft Active Directory

Hi, we are very glad that our efforts helped someone ) Good luck!

Best regards,
Zholaman

Hi @NBAMj,

I dont Think there is any logic in the Flowable LDAP module for pagination of users. It always tries to return a full list based on the ldap.query.userall expression regardless of which page you request.

You’d need to see if you can add this as a feature request.

Regards,
Paul

Good idea, I will create a feature request for that. :slight_smile:

Hi,

Can you plz provide a documentation explaining the ldap configuration in details. I have no experience in ldap or active directory. can you guide me right direction to understand the configuration in detail?

Thank You,
Arpit Agrawal

These docs: https://www.flowable.org/docs/userguide/index.html#chapter_ldap ?

Cheers
Paul.

Hi @Zholaman,

Can you help me? I am trying to integrate LDAP wth flowable, i am currently using a test LDAP server


but i am getting 401 when authenticating with idm user. Here is the LDAP configuration i am using in idm,

ldap.enabled=true
ldap.server=ldap://ldap.forumsys.com
ldap.port=389
ldap.user=cn=read-only-admin,dc=example,dc=com
ldap.password=password
ldap.basedn=dc=example,dc=com
ldap.userbasedn=ou=mathematicians,dc=example,dc=com
ldap.query.userbyid=(&(objectClass=inetOrgPerson)(uid={0}))
ldap.query.userbyname=(&(objectClass=inetOrgPerson)(|({0}=*{1}*)({2}=*{3}*)))
ldap.query.userall=(objectClass=inetOrgPerson)
ldap.query.groupsforuser=(&(objectClass=groupOfUniqueNames)(uniqueMember={0}))
ldap.query.groupall=(objectClass=groupOfUniqueNames)
ldap.attribute.userid=uid
ldap.attribute.firstname=cn
ldap.attribute.lastname=sn
ldap.attribute.email=mail
ldap.attribute.groupid=cn
ldap.attribute.groupname=cn
ldap.cache.groupsize=10000
ldap.cache.groupexpiration=180000

admin.userid=read-only-admin

I am new to LDAP and Active Directory stuff. So, need help figuring out how to integrate.

Thank You,
Arpit Agrawal

Hi Arpit,

as I remember there is a little difference between LDAP and AD. So let me ask, what the final goal is to integrate with AD or with LDAP ?

Best regards,
Zholaman

Hi @Zholaman,

I am new to this stuff so don’t know much difference. Let’s say I want to do both but for now, how can I integrate LDAP. Also, it would be helpful if you can provide how the solution will be different for AD?

Thank You,
Arpit Agrawal

Arpit,

I don’t remember what I did for LDAP and AD. But I remember that there is difference in configuration option between LDAP and AD. I configure Flowable almost a year ago, I haven’t touched it since.

What type of OS do you use ? I can prepeare an step-by-step instruction in my spare time. But I can’t guarantee I’ll do it fast. :slight_smile:

Kind regards,
Zholaman

Hi @Zholaman,

I am using ubuntu 16.04. Sure, no problem. Post it here only so any newbies like me can get benefits out of it.

But i am little short of time. So, if anyone else on this thread can help me, i would be really grateful.

Thank You,
Arpit Agrawal

Arpit,

OK, the web link will be here.

Best regards,
Zholaman

Hi @Zholaman,

I am able to authenticate the user now, but user is not able to access the apps. Do you remember how you gave privileges to user to access app ??

Reference Post for details :

Thank you,
Arpit Agrawal

Arpit,

excellent, now seems you need to use flowable-idm to provide an access to user.

Best regards,
Zholaman

@Zholaman,

That is the issue. I added “boyle” as admin.userid in application properties but when i login through boyle i get 401 error. How to give access to the user is my question?

Thank you,
Arpit Agrawal

Hi @Zholaman,

Migrating idm to fresh database solved the problem. By default “boyle” got access(when idm setup database for 1st time) to all the apps but i am not able i am not getting users list from LDAP in the idm app although i am getting all the available groups from LDAP. Any idea how can i get list of users(i am guessing some problem with the getAllUsers query)? Also, migrating to fresh database isn’t a good solution, any idea how can we solve it?

Thank You,
Arpit Agrawal

1 Like

Arpit,

if you are getting all groups from LDAP it mean connection is working. Now you can play with these options:

ldap.basedn=dc=example,dc=com (path to your users and groups)
ldap.userbasedn=ou=mathematicians,dc=example,dc=com (path to your LDAP users)
ldap.query.userbyid=(&(objectClass=inetOrgPerson)(uid={0}))
ldap.query.userbyname=(&(objectClass=inetOrgPerson)(|({0}={1})({2}={3})))
ldap.query.userall=(objectClass=inetOrgPerson)

ldap.attribute.userid=uid
ldap.attribute.firstname=cn
ldap.attribute.lastname=sn
ldap.attribute.email=mail

I think you on the right way ))

Best regards,
Zholaman

Hi @Zholaman,

i tried this query ldap.query.userall=(&(objectClass=inetOrgPerson)(uid=*)) and i am getting all the users(dont know how correct or wrong this query is but its giving results). Now where can i add the query to get users for a particular group? I see only query to get either users or groups, but no query to get users of a group. Also, on the group tab of flowable-idm, when i click on any group, ideally it should show me users belonging to that group, but its not showing anything and giving Internal Server Error

HTTP Status 500 - Request processing failed; nested exception is 
org.flowable.engine.common.api.FlowableException: Query return 4 results instead of max 1
type Exception report

message Request processing failed; nested exception is 
org.flowable.engine.common.api.FlowableException: Query return 4 results instead of max 1

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is 
org.flowable.engine.common.api.FlowableException: Query return 4 results instead of max 1
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
root cause

org.flowable.engine.common.api.FlowableException: Query return 4 results instead of max 1
org.flowable.engine.common.impl.AbstractQuery.executeSingleResult(AbstractQuery.java:165)
org.flowable.engine.common.impl.AbstractQuery.singleResult(AbstractQuery.java:106)
org.flowable.app.idm.service.GroupServiceImpl.getGroup(GroupServiceImpl.java:50)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
com.sun.proxy.$Proxy1230.getGroup(Unknown Source)
org.flowable.app.rest.idm.IdmGroupsResource.getGroup(IdmGroupsResource.java:55)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.77 logs.

Apache Tomcat/7.0.77

Any idea on this?

Thank You,
Arpit Agrawal

Arpit,

Q: "…but no query to get users of a group…"
A: As you can see, there is no option to get users from particular group. But you can get a users which belong to some Class, for example: objectClass=inetOrgPerson

Q: "on the group tab of flowable-idm, when i click on any group,… it should show me users belonging to that group but its not showing anything "
A: I also faced with this error. I think this error need a deep knowledge of Flowable’s source code. I do not have this knowledge BUT I can give you an advice. If you have a time and wish you can start investigation from the sources responsible for LDAP.

Best regards,
Zholaman

Hi @Zholaman,

I think users from particular group should be the query which will be used when i click on any group in the group tab of idm. The reason i need this query is because there is no way otherwise to know which user belong to which group from idm. I did see the source LDAP but looks like by default they are only reading these 5 queries when initializing ldap. So might need to change in the LDAP source to read new custom queries also. Anyways, thanks for the support and help you provided :slight_smile:

Thank you,
Arpit Agrawal

Arpit,

Thanks, Good luck!

Best regards,
Zholaman