Announcement Announcement Module
Collapse
No announcement yet.
Mixing Namespace and bean config in getting authorities from AD LDAP server Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mixing Namespace and bean config in getting authorities from AD LDAP server

    I am currently using Spring security 3.0.7 to authenticate and authorize users in our webapp.

    We authenticate with x509 client certs and want to get authorities from our 2008 AD/LDAP server.

    I can authenticate with my client cert but the getting of authorities fails with a "Unprocessed Continuation Reference; remaining name '' " exception

    I am attempting to work through the fixes for this but I think I am incorrectly wiring up the beans portion. I think this because I stepped the code and saw that my settings for the authoritiesPopulator were not being used and rather the defaults were being used.

    Despite using the Spring Security 3 book by Peter Mularien I am still lost.

    security config below . Any help appreciated.

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"/>
    
    
    
        <http auto-config="true" use-expressions="true">
            <intercept-url pattern="/css/**" filters="none" />
            <intercept-url pattern="/js/**" filters="none" />
            <intercept-url pattern="/img/**" filters="none" />
    
            <intercept-url pattern="/login" access="permitAll" />
            <intercept-url pattern="/logout" access="permitAll" />
            <intercept-url pattern="/**" access="hasRole("ROLE_ADMIN")" />
            <intercept-url pattern="/**" access="hasRole("ROLE_USER_GROUPA")" />
            <intercept-url pattern="/**" access="hasRole("ROLE_USER_GROUPB")" />
    
    
    
    	<x509 subject-principal-regex="CN(.*?)," user-service-ref="ladpUserService"/>	
    
        </http>
    
    <authentication-manager alias="authenticationManager">
    	<authentication-provider>
    	<user-service>
    	<!-- A User with this cert name can authenticate and get this role correctly -->
    		<user authorities="ROLE_ADMIN" name="test_user">
    	<!-- I would really like to be able to add authorities for groups similar to this construct, where group=AD group
    		<user authorities="ROLE_USER_GROUPA" group="GROUPA">
    		<user authorities="ROLE_USER_GROUPB" group="GROUPB">-->
    	</user-service>
    	</authentication-provider>
    </authentication-manager>
    
    
    <ldap-user-service id="ldapUserService" server-ref="ldapServer" user-search-filter="(cn={0})"/>
    <ldap-server id="ldapServer" url="x.x.x.x:389/DC=com,DC=test,DC=server" manager-dn="CN=LookupUser,CN=Users,DC=com,DC=test,DC=server" manager-password="secret"/>
    
    
    
    	<beans:bean id="authoritiesPopulator" class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
    	    <beans:constructor-arg ref="contextSource" />
    	    <beans:constructor-arg value="CN=Users" />
    	    <beans:property name="searchSubtree" value="true" />
    	    <beans:property name="groupSearchFilter" value="(memberOf={0})" />
    	</beans:bean>
    
    
    
    
    
        <beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
            <beans:constructor-arg value=""x.x.x.x:389/DC=com,DC=test,DC=server"/>
            <beans:property name="userDn" value="CN=LookupUser,CN=Users,DC=com,DC=test,DC=server"/>
            <beans:property name="password" value="secret"/>
    	<beans:property name="base" value=""/>
    	<beans:property name="baseEnvironmentProperties">
    	<beans:map>
    	<beans:entry key="java.naming.refferal" value="follow"/>
    	</beans:map>
    	</beans:property>
        </beans:bean>
    
       
    
    </beans:beans>

  • #2
    additional information

    I discovered that my ldap search is returns the correct user and its attributes.

    inside SpringSecurityLdapTemplate It gets the results set object which contains originalAttrs which contains the attrs hashtable.

    That hashtable contains all attributes supplied by the ldap server. The problem seems to be related to getting the attribute I need ( memberOf ) and mapping the member of results to ROLES.

    The line

    Code:
    results.add(new DirContextAdapter(searchResult.getAttributes(),dn,ctxBaseDN));
    loops across the results Resulting in a userData object which drops us into LdapUserDetailsService,loadUserByUsername and then to the DefaultLdapAuthoritiesPopulator.getGroupMembership Roles

    from there even though we have a user object which has the attributes we go back to SpringSecurityLdapTemplate.searchForSingleAttribut eValues

    here it uses a filter of (uniqueMember={0}) and an attribute name of "cn" to search the LDAP server again .

    This is where is comes apart .. the search should at least return the cn for the user . Using the filter from the log and the cn attribute I find a record using LDAP search directly outside spring.

    Since the the CN is "test_user" and "test_user" has a role should'nt this authenticate ?

    Also I am a little confused as to why the security context clears the authenticated when no valid authorites are found . In this case the user is authenticated via X509 they just have no role.

    Comment


    • #3
      Ok I have found where my problem is

      in SpringSecurityLdapTemplate.searchForSingleAttribut eValues

      Specifically it accepts four arguments. groupSearchBase,groupSearchFilter,groupRoleAttribu te are all easily configureable.

      However it also accepts a list of the userDn and username. These are used to construct the filter .

      The problem seems to be that 2008 AD LDS server expects the searchBase to hold the params and returns bogus ( empty ) results for attributes when the base and the filter contain duplicate values .

      For example

      using
      BaseDN:CN:Users,DC=my,DC=serv,DC=local
      Filter : (cn=test_user)
      scope : subtree
      Attributes : memberOf

      returns all the attributes however using

      BaseDN:CN:Users,DC=my,DC=serv,DC=local
      Filter : (cn=test_user,CN=Users,DC=my,DC=serv,DC=local)
      scope : subtree
      Attributes : memberOf

      returns an empty set

      So the question is how can I get Spring security to stop adding the DN onto the filter ? Does the 3.1.0.RC3 AD "connector" solve this issue ?

      Comment


      • #4
        OK so it seems the best (?) path to using the memberOf in AD is to write my own ldapAuthoritiesPopulator.

        so given the config below ( which all works correctly minus the mapping of memberOf to roles ) how can I implement this ?

        I tried a custom bean as follows but its seems I need more .

        <beans:bean class:"my.app.CustomRoleGranter" id="ldapAuthoritiesPopulator"/> <-- this does not work.

        Any help would be appreciated .

        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        <beans:beans xmlns="http://www.springframework.org/schema/security
            xmlns:beans="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"/>
        
        
        
            <http auto-config="true" use-expressions="true">
                <intercept-url pattern="/css/**" filters="none" />
                <intercept-url pattern="/js/**" filters="none" />
                <intercept-url pattern="/img/**" filters="none" />
        
                <intercept-url pattern="/login" access="permitAll" />
                <intercept-url pattern="/logout" access="permitAll" />
                <intercept-url pattern="/**" access="hasRole("ROLE_ADMIN")" />
                <intercept-url pattern="/**" access="hasRole("ROLE_USER_GROUPA")" />
                <intercept-url pattern="/**" access="hasRole("ROLE_USER_GROUPB")" />
        
        
        
        	<x509 subject-principal-regex="CN(.*?)," user-service-ref="ladpUserService"/>	
        
            </http>
        
        <authentication-manager alias="authenticationManager">
        	<authentication-provider>
        	<user-service>
        	<!-- A User with this cert name can authenticate and get this role correctly -->
        		<user authorities="ROLE_ADMIN" name="test_user">
        	</user-service>
        	</authentication-provider>
        </authentication-manager>
        
        
        <ldap-user-service id="ldapUserService" server-ref="ldapServer" user-search-filter="(cn={0})" group-search-base="CN=Users,DC=com,DC=test,DC=server" group-search-filter="(dn={0})" group-role-attribute="memberOf"/> 
        <ldap-server id="ldapServer" url="x.x.x.x:389" manager-dn="CN=LookupUser,CN=Users,DC=com,DC=test,DC=server" manager-password="secret"/>
        
           
        
        </beans:beans>

        Comment


        • #5
          Not if these will be any use or not but I found these to be useful when trying to work how to get my AD Authentication working

          http://vratnagiri.blogspot.com/2010/...tory-over.html

          http://www.jeviathon.com/2009/08/spr...iguration.html

          Comment

          Working...
          X