Spring security authentication using ldap based on memberOf attribute

6.4k views Asked by At

I'm using spring authentication against ldap. If the provided user id and password exists in ldap, then I was able to get the user login. I would like to restrict this based on the user's memberOf attribute in the LDAP. If the user has memberOf attribute with a specific CN value (CN=adminaccess or CN=superadminaccess), then authentication/authorization should pass.Else authentication/authorization should fail.

<security:http auto-config="true" use-expressions="true" access-denied-page="/admin/auth/denied">
    <security:intercept-url pattern="/admin/auth/login" access="permitAll" />
    <security:intercept-url pattern="/admin/dashboard/*" access="hasAnyRole('ROLE_ADMINACCESS','ROLE_SUPERADMINACCESS')"/>
</security:http>

<security:authentication-manager>   
  <security:ldap-authentication-provider   user-dn-pattern="CN={0},CN=Users" group-search-base="CN=adminaccess,CN=Users" />  
</security:authentication-manager>

<bean id="ldapContext"
        class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <constructor-arg value="ldap://xxx.ds.yyy.com:389/DC=xxx,DC=ds,DC=yyy,DC=com"/>
    <property name="userDn" value="CN=aaa,CN=Users,DC=xxx,DC=ds,DC=yyy,DC=com"/>
    <property name="password" value="thepassword"/>
</bean>

I always go to the Access Denied page with my above configuration. If I remove the access="hasAnyRole('ROLE_ADMINACCESS','ROLE_SUPERADMINACCESS')" from the security:intercept-url, I'm able to always access with valid user/password, even if the user is not part of adminaccess (which I was hoping would be restricted because my group -search-base had specified CN=adminaccess). Wondering what the configuration should be:

  1. To restrict access to just users who are memberOf CN=adminaccess and/or CN=superadminaccess
  2. Specify correct group-search-base. If I specify only CN=Users, I'm getting a timeout as this is going against our corporate ldap. When I looked up users on LDAP browser, I couldnt find a "ou" that couldhelp. With my above configuration group-search-base="CN=adminaccess,CN=Users", I dont get a timeout, but I dont think it is correct either
1

There are 1 answers

1
ignatan On BEST ANSWER

Not sure if there is a better way, but I was able to successfully get this working using DefaultLdapAuthoritiesPopulator and updating to the below configuration:

<security:http auto-config="true" use-expressions="true" access-denied-page="/admin/auth/denied">
<security:intercept-url pattern="/admin/auth/login" access="permitAll" />
<security:intercept-url pattern="/admin/dashboard/*" access="hasAnyRole('ROLE_ADMINACCESS','ROLE_SUPERADMINACCESS')"/>
</security:http>

<security:authentication-manager>
    <security:authentication-provider
        ref="ldapAuthProvider"></security:authentication-provider>
</security:authentication-manager>

<bean id="ldapContext"
    class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
 <constructor-arg value="ldap://xxx.ds.yyy.com:389/DC=xxx,DC=ds,DC=yyy,DC=com"/>
 <property name="userDn" value="CN=aaa,CN=Users,DC=xxx,DC=ds,DC=yyy,DC=com"/>
 <property name="password" value="thepassword"/>
</bean>

<bean id="ldapAuthProvider"
     class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <constructor-arg>
        <bean
            class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <constructor-arg ref="ldapContext" />
            <property name="userDnPatterns">
                <list>
                    <value>CN={0},CN=Users</value>
                </list>
            </property>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean
            class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
            <constructor-arg ref="ldapContext" />
            <constructor-arg value="CN=Users" />
            <property name="groupRoleAttribute" value="CN" />
        </bean>
    </constructor-arg>
</bean>

With this configuration, if the login username/password provided is correct, all the groups that the user is "memberOf" (pattern CN=Users,DC=xxx,DC=ds,DC=yyy,DC=com), get loaded as his "roles" (prefixed with ROLE_) and I'm able to manage access to these roles using security:intercept-url