Jump to content
We've recently updated our Privacy Statement, available here ×

LDAP (AD 2012) Nested AD Groups and Role Mapping


tuser.ja
Go to solution Solved by tuser.ja,

Recommended Posts

JasperReports 6.3.0 CE (WAR distro on Tomcat7 JDK7)

After a considerable amount of reading documentation, cookbooks, and community posts, I can officially say this has been one of the most esoteric LDAP integrations I've ever performed.  I'm currently trying to get jasper to map internal roles to users who are not diretly members of role mapped AD groups.  I appreciate your time and hope that someone with more direct experience with spring and LDAP (which I'm currently reading) can provide an easy fix or at least something to guide me down the right path.  As with every detail of this configuration I'm sure it's something small but impactful.

I'm currently trying to get user roles assigned when authenticated users are members of nested groups in AD.  Only users who are members of groups within the Jasper* group structure should be authenticated.

Jasper-Group-Memberships.png.571016049fa079ede536b3591b15c764.png

For example our test user:

Test User (tuser@ihazthadumb.com) (CN=Test User,OU=Test Accounts,OU=Service Accounts,OU=O365 Synced,DC=ihazthadumb,DC=com)[/code]

Is a member of

ihtd - IM (ihtd-im@ihazthadumb.com,) (CN=ihtd - IM,OU=Groups,OU=O365 Synced,DC=ihazthadumb,DC=com)[/code]

Which is a member of

Jasper_IM (no smtp) (CN=Jasper_IM,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com)[/code]

which is a member of

Jasper_Users (no smtp) (CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com)[/code]

Authentication is working.  As is authorization (via role mapping) when the user is directly a member of the mapped role group.

Searching for user 'tuser@ihtd.com', with user search [ searchFilter: '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]2017-04-24 12:27:34,520 DEBUG FilterBasedLdapUserSearch,http-nio-8443-exec-12:107 - Searching for user 'tuser@ihtd.com', with user search [ searchFilter: '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]2017-04-24 12:27:34,979 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-12:211 - Searching for entry under DN 'dc=ihazthadumb,dc=com', base = '', filter = '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))'2017-04-24 12:27:34,979 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-12:211 - Searching for entry under DN 'dc=ihazthadumb,dc=com', base = '', filter = '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))'2017-04-24 12:27:34,984 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-12:223 - Found DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced2017-04-24 12:27:34,984 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-12:223 - Found DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced2017-04-24 12:27:35,360 DEBUG BindAuthenticator,http-nio-8443-exec-12:108 - Attempting to bind as cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:27:35,360 DEBUG BindAuthenticator,http-nio-8443-exec-12:108 - Attempting to bind as cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:27:35,434 DEBUG BindAuthenticator,http-nio-8443-exec-12:116 - Retrieving attributes...2017-04-24 12:27:35,434 DEBUG BindAuthenticator,http-nio-8443-exec-12:116 - Retrieving attributes...2017-04-24 12:27:35,445 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-12:182 - Getting authorities for user cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:27:35,445 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-12:182 - Getting authorities for user cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:27:35,448 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-12:211 - Searching for roles for user 'tuser@ihtd.com', DN = 'cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com', with filter (&(objectclass=group)(member={0})(cn=jasper_*)) in search base ''2017-04-24 12:27:35,448 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-12:211 - Searching for roles for user 'tuser@ihtd.com', DN = 'cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com', with filter (&(objectclass=group)(member={0})(cn=jasper_*)) in search base ''2017-04-24 12:27:35,449 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-12:150 - Using filter: (&(objectclass=group)(member=cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com)(cn=jasper_*))2017-04-24 12:27:35,449 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-12:150 - Using filter: (&(objectclass=group)(member=cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com)(cn=jasper_*))2017-04-24 12:27:35,885 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-12:219 - Roles from search: [Jasper_IM]2017-04-24 12:27:35,885 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-12:219 - Roles from search: [Jasper_IM]2017-04-24 12:27:35,887 DEBUG LdapUserDetailsMapper,http-nio-8443-exec-12:51 - Mapping user details from context with DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:27:35,887 DEBUG LdapUserDetailsMapper,http-nio-8443-exec-12:51 - Mapping user details from context with DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com[/code]

However, if the user is a member of another (security) group - which is a member of the mapped jasper role group the role search comes back empty

2017-04-24 12:30:50,852 DEBUG FilterBasedLdapUserSearch,http-nio-8443-exec-18:107 - Searching for user 'tuser@justassociates.com', with user search [ searchFilter: '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]2017-04-24 12:30:50,852 DEBUG FilterBasedLdapUserSearch,http-nio-8443-exec-18:107 - Searching for user 'tuser@justassociates.com', with user search [ searchFilter: '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]2017-04-24 12:30:51,284 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-18:211 - Searching for entry under DN 'dc=ihazthadumb,dc=com', base = '', filter = '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))'2017-04-24 12:30:51,284 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-18:211 - Searching for entry under DN 'dc=ihazthadumb,dc=com', base = '', filter = '(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/ Role Groups,DC=ihazthadumb,DC=com))))'2017-04-24 12:30:51,288 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-18:223 - Found DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced2017-04-24 12:30:51,288 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-18:223 - Found DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced2017-04-24 12:30:51,646 DEBUG BindAuthenticator,http-nio-8443-exec-18:108 - Attempting to bind as cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:30:51,646 DEBUG BindAuthenticator,http-nio-8443-exec-18:108 - Attempting to bind as cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:30:51,732 DEBUG BindAuthenticator,http-nio-8443-exec-18:116 - Retrieving attributes...2017-04-24 12:30:51,732 DEBUG BindAuthenticator,http-nio-8443-exec-18:116 - Retrieving attributes...2017-04-24 12:30:51,741 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-18:182 - Getting authorities for user cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:30:51,741 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-18:182 - Getting authorities for user cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:30:51,742 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-18:211 - Searching for roles for user 'tuser@justassociates.com', DN = 'cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com', with filter (&(objectclass=group)(member={0})(cn=jasper_*)) in search base ''2017-04-24 12:30:51,742 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-18:211 - Searching for roles for user 'tuser@justassociates.com', DN = 'cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com', with filter (&(objectclass=group)(member={0})(cn=jasper_*)) in search base ''2017-04-24 12:30:51,744 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-18:150 - Using filter: (&(objectclass=group)(member=cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com)(cn=jasper_*))2017-04-24 12:30:51,744 DEBUG SpringSecurityLdapTemplate,http-nio-8443-exec-18:150 - Using filter: (&(objectclass=group)(member=cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com)(cn=jasper_*))2017-04-24 12:30:52,152 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-18:219 - Roles from search: []2017-04-24 12:30:52,152 DEBUG DefaultLdapAuthoritiesPopulator,http-nio-8443-exec-18:219 - Roles from search: []2017-04-24 12:30:52,155 DEBUG LdapUserDetailsMapper,http-nio-8443-exec-18:51 - Mapping user details from context with DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com2017-04-24 12:30:52,155 DEBUG LdapUserDetailsMapper,http-nio-8443-exec-18:51 - Mapping user details from context with DN: cn=Test User,ou=Test Accounts,ou=Service Accounts,ou=O365 Synced,dc=ihazthadumb,dc=com[/code]

Here is our AD layout:

Jasper-AD.png.c734ab2a092c90c9ead3f7063fc115c2.png

Here's the LDAP config from my applicationContext-externalAuth-LDAP.xml (All other lines remain default)

<bean id="ldapAuthenticationProvider"      class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSLdapAuthenticationProvider">    <constructor-arg>        <bean class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSBindAuthenticator">            <constructor-arg>                <ref local="ldapContextSource"/>            </constructor-arg>            <property name="userSearch" ref="userSearch"/>        </bean>    </constructor-arg>    <constructor-arg>        <bean class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSDefaultLdapAuthoritiesPopulator">            <constructor-arg index="0">                <ref local="ldapContextSource"/>            </constructor-arg>            <constructor-arg index="1">                <value></value>            </constructor-arg>            <property name="groupRoleAttribute" value="cn"/>            <property name="convertToUpperCase" value="true"/>            <property name="rolePrefix"         value="ROLE_"/>            <property name="groupSearchFilter"  value="(&(objectclass=group)(member={0})(cn=jasper_*))"/>            <property name="searchSubtree"      value="true"/>             <!-- Can setup additional external default roles here  <property name="defaultRole" value="LDAP"/> -->        </bean>    </constructor-arg></bean><bean id="userSearch" class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSFilterBasedLdapUserSearch">    <constructor-arg index="0">        <value></value>    </constructor-arg>    <constructor-arg index="1">      <value>(&(userPrincipalName={0})(&((objectclass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Jasper_Users,OU=Authorization/Role Groups,DC=ihazthadumb,DC=com))))</value>    </constructor-arg>    <constructor-arg index="2">        <ref local="ldapContextSource" />    </constructor-arg>    <property name="searchSubtree">        <value>true</value>    </property></bean><bean id="ldapContextSource"      class="com.jaspersoft.jasperserver.api.security.externalAuth.ldap.JSLdapContextSource">    <constructor-arg value="ldaps://kittens.ihazthadumb.com:636/dc=ihazthadumb,dc=com"/>    <!-- manager user name and password -->    <property name="userDn"   value="CN=LDAP Authentication,OU=Application Service Accounts,DC=ihazthadumb,DC=com"/>    <property name="password" value="This is a really long passphrase hopefully nobody would ever want to type out just to get access to AD/LDAP.  Is it more secure?  You decide."/>    <property name="referral" value="follow" /></bean> <bean id="externalUserSetupProcessor" class="com.jaspersoft.jasperserver.api.security.externalAuth.processors.ExternalUserSetupProcessor" parent="abstractExternalProcessor">    <!--Default permitted role characters; others are removed. Change regular expression to allow other chars.        <property name="permittedExternalRoleNameRegex" value="[A-Za-z0-9_]+"/>-->    <property name="userAuthorityService">        <ref bean="${bean.internalUserAuthorityService}"/>    </property>    <property name="defaultInternalRoles">        <list>            <value>ROLE_USER</value>        </list>    </property>    <property name="organizationRoleMap">        <map>            <!-- Mapping Group Names Created as Jasper Roles to JRS Internal Roles -->            <entry>                <key>                    <value>ROLE_JASPER_ADMINISTRATORS</value>                </key>                <value>ROLE_ADMINISTRATOR</value>            </entry>            <entry>                <key>                    <value>ROLE_JASPER_IM</value>                </key>                <value>ROLE_IM</value>            </entry>            <entry>                <key>                    <value>ROLE_JASPER_SUPERVISORS</value>                </key>                <value>ROLE_SUPERVISORS</value>            </entry>            <entry>                <key>                    <value>ROLE_JASPER_TRAINING</value>                </key>                <value>ROLE_TRAINING</value>            </entry>        </map>    </property></bean>[/code]

 

Link to comment
Share on other sites

  • Replies 4
  • Created
  • Last Reply

Top Posters In This Topic

  • Solution

After much trial and error, and some assumption on my part based on the existing UserSearch filter I have found the solution to my problem.  I hope this helps anyone wanting to leverage existing groups and user memberships, while still having a specific, manageable, configuration for including Jasper Reports into the organization's directory services for authentication and wuthorization.

Refernced documentation:
http://community.jaspersoft.com/documentation/jasperreports-server-authentication-cookbook/mapping-user-roles
http://community.jaspersoft.com/blog/jasperserver-user-authentication-microsoft-active-directory
http://community.jaspersoft.com/wiki/secure-active-directoryldapldaps-authentication-groups
http://forum.spring.io/forum/spring-projects/data/ldap/107516-find-all-sub-groups-of-all-depths-of-a-given-group-in-ldap-using-ldaptemplate
 

I changed the group search filter from:
<value>(&(member={0})(objectclass=group)(cn=jasper_*))</value>
Which expects to find a user as a direct member of a group beginning with "jasper_" to match a role

to:
<property name="groupSearchFilter" value="(&((objectClass=group)(member:1.2.840.113556.1.4.1941:={0})(cn=jasper_*)))"/>
Which, like the userSearch, recursively searches through the user's memberships for a group matching "jasper_" to match and map a role.

It is my understanding based on what I've read from the Spring documentation and other posts that the recursive functionality is not present in all LDAP implementations.  The referenced article https://msdn.microsoft.com/en-us/library/aa746475%28VS.85%29.aspx indicates that the rule OID above:

1.2.840.113556.1.4.1941LDAP_MATCHING_RULE_IN_CHAINThis rule is limited to filters that apply to the DN. This is a special "extended" match operator that walks the chain of ancestry in objects all the way to the root until it finds a match.


 

Link to comment
Share on other sites

  • 4 weeks later...
  • 11 months later...
  • 4 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...