Sunday, June 11, 2017

Authenticating ldap user with multiple suffix value/domain

Leave a Comment

I am trying to authenticate and then query AD tree using Spring Ldap Security and Spring Ldap.

Following is my configuration file -

<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xmlns:beans="http://www.springframework.org/schema/beans"     xmlns:ldap="http://www.springframework.org/schema/ldap"     xmlns:util="http://www.springframework.org/schema/util"     xsi:schemaLocation="         http://www.springframework.org/schema/security          http://www.springframework.org/schema/security/spring-security-3.2.xsd         http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd         http://www.springframework.org/schema/context          http://www.springframework.org/schema/context/spring-context.xsd          http://www.springframework.org/schema/ldap          http://www.springframework.org/schema/ldap/spring-ldap.xsd         http://www.springframework.org/schema/util          http://www.springframework.org/schema/util/spring-util.xsd">      <http use-expressions="true">         <form-login login-page="/myApp/ldap" default-target-url="/myApp/ldap/config"             authentication-failure-url="/myApp/ldap?error=true" />         <logout />     </http>      <beans:bean         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">         <beans:property name="location">             <beans:value>classpath:/ldap.properties</beans:value>         </beans:property>         <beans:property name="SystemPropertiesMode">             <beans:value>2</beans:value>         </beans:property>     </beans:bean>      <beans:bean id="adAuthenticationProvider" scope="prototype"         class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">         <!-- the domain name (may be null or empty). If no domain name is configured, it is assumed that the username will always contain the domain name. -->         <beans:constructor-arg index="0" value="${sample.ldap.domain}" />         <!-- an LDAP url (or multiple URLs) -->         <beans:constructor-arg index="1" value="${sample.ldap.url}" />         <!-- Determines whether the supplied password will be used as the credentials in the successful authentication token. -->         <beans:property name="useAuthenticationRequestCredentials"             value="true" />         <!-- by setting this property to true, when the authentication fails the error codes will also be used to control the exception raised. -->         <beans:property name="convertSubErrorCodesToExceptions"             value="true" />     </beans:bean>      <authentication-manager erase-credentials="false">         <authentication-provider ref="adAuthenticationProvider" />     </authentication-manager>      <beans:bean         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">         <beans:property name="location">             <beans:value>classpath:/ldap.properties</beans:value>         </beans:property>         <beans:property name="SystemPropertiesMode">             <beans:value>2</beans:value> <!-- OVERRIDE is 2 -->         </beans:property>     </beans:bean>      <ldap:context-source id="contextSource"                           url="${sample.ldap.url}"                          base="${sample.ldap.base}"                           referral="follow"                          authentication-source-ref="authenticationSource"                           base-env-props-ref="baseEnvironmentProperties"/>      <util:map id="baseEnvironmentProperties">         <beans:entry key="com.sun.jndi.ldap.connect.timeout" value="60000" />         <beans:entry key="java.naming.ldap.attributes.binary" value="objectGUID objectSid"/>     </util:map>      <beans:bean id="authenticationSource"         class="org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource" />      <ldap:ldap-template id="ldapTemplate"         context-source-ref="contextSource" />  </beans:beans> 

And property file is -

sample.ldap.url=ldap://xxx.xxx.xxx.xxx:3268 sample.ldap.base=dc=example,dc=com sample.ldap.clean=true sample.ldap.directory.type=AD sample.ldap.domain=example.com 

These setting works fine for following login -

username - example@example.com or example Password - blah

but fails when i try - username - example2@example.net or example Password - blah2

These both are valid logins, and have been validated by login using AD Explorer.

Seems like i need to update my configuration to support UPN suffix/domains as default works fine and other do not.

Is there a way i can append to this config file to support this logic, supporting authenticating/querying multiple domains?

2 Answers

Answers 1

To explain @NewBee's solution:

1 ActiveDirectoryLdapAuthenticationProvider:

  • Specialized LDAP authentication provider which uses Active Directory configuration conventions.
  • It will authenticate using the Active Directory userPrincipalName or sAMAccountName (or a custom searchFilter) in the form username@domain. If the username does not already end with the domain name, the userPrincipalName will be built by appending the configured domain name to the username supplied in the authentication request. If no domain name is configured, it is assumed that the username will always contain the domain name.
  • The user authorities are obtained from the data contained in the memberOf attribute.

2 LDAP authentication in Spring Security:

  • Obtaining the unique LDAP Distinguished Name, or DN, from the login name.

    • This will often mean performing a search in the directory, unless the exact mapping of usernames to DNs is known in advance. So a user might enter his/her name when logging in, but the actual name used to authenticate to LDAP will be the full DN, such as uid=(username),ou=users,dc=springsource,dc=com.
  • Authenticating the user, either by binding as that user or by performing a remote compare operation of the user's password against the password attribute in the directory entry for the DN.

  • Loading the list of authorities for the user.

For a reference to How to configure multiple UPN Suffixes. Plus in ActiveDirectoryLdapAuthenticationProvider you could write a function for reading multiple suffixes, as the library is adaptable.

Answers 2

Reason it's not allowing me to login with configured UPN suffix is because ActiveDirectoryLdapAuthenticationProvider seems to be making assumption that UPN suffix is always same as Domain Name.

Please refer this post - https://github.com/spring-projects/spring-security/issues/3204

I think there should be a better way to handle this though, or maybe better library for authentication.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment