title: Spring ActiveDirectoryLdapAuthenticationProvider setSearchFilter method
body: <p>I have a working setup for SpringFramework Security 4.0.0 with my AD server. This was working fine with the default search filter until I discovered that the users in the AD database are much more twisted than expected originally.</p>
  
  <p>My setup was as follow for the ActiveDirectoryLdapAuthenticationProvider bean in the namespace:</p>
  
  <pre><code>&lt;b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider"&gt;
      &lt;b:constructor-arg value="subdom1.dom1.com" /&gt;
      &lt;b:constructor-arg value="ldap://fsapps.company.uni:389/" /&gt;
      &lt;b:constructor-arg value="dc=fsapps,dc=company,dc=uni" /&gt;
      &lt;b:property name="searchFilter" value="(&amp;amp;(userPrincipalName={0})(objectClass=user))" /&gt;
      &lt;b:property name="userDetailsContextMapper"&gt;
          &lt;b:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" /&gt;
      &lt;/b:property&gt;
      &lt;b:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" /&gt;
      &lt;b:property name="convertSubErrorCodesToExceptions" value="true" /&gt;
  &lt;/b:bean&gt;
  </code></pre>
  
  <p>I then moved to the following setup instead to remove the dependency on the domain:</p>
  
  <pre><code>&lt;b:bean id="monFournisseurAD" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider"&gt;
      &lt;b:constructor-arg value="" /&gt;
      &lt;b:constructor-arg value="ldap://fsapps.company.uni:389/" /&gt;
      &lt;b:constructor-arg value="dc=fsapps,dc=company,dc=uni" /&gt;
      &lt;b:property name="searchFilter" value="(&amp;amp;(sAMAccountName={0})(objectClass=user))" /&gt;
      &lt;b:property name="userDetailsContextMapper"&gt;
          &lt;b:bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" /&gt;
      &lt;/b:property&gt;
      &lt;b:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" /&gt;
      &lt;b:property name="convertSubErrorCodesToExceptions" value="true" /&gt;
  &lt;/b:bean&gt;
  </code></pre>
  
  <p>The problem now is the {0} substitution in the searchFilter accordingly to the SpringFramework Security 4.0.0 documentation is substituting username@domain where domain seems to be the default domain of the AD server itself, which in this case is fsapps.company.uni since my first constructor argument is empty. <a href="http://docs.spring.io/autorepo/docs/spring-security/4.0.0.RELEASE/apidocs/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.html" rel="nofollow">SpringFramework Security 4.0.0 Class ActiveDirectoryLdapAuthenticationProvider's documentation</a></p>
  
  <p>Question: Is there a way to substitute only username rather than username@domain? Any other suggestions how I can circumvent this problem?</p>
  
  <p><em>NOTE:</em> After looking at the source code. It seems the expected behavior should be as follow: if the domain argument for the constructor of the class ActiveDirectoryLdapAuthenticationProvider is an empty string or an all white spaces string, it is set to null. When the domain is set to null, the substitution of the {0} pattern should be the username only without the domain appended to it and this should do exactly what I want it to do: search for the sAMAccountName attribute equals to the username alone and a record of objectClass user. So, why does it fail to find users which are not in the rootDN as a domain (third constructor's argument fsapps.company.com in my example)? I have no problem to match users which would have a userPrincipalName of the form: username@fsapps.company.com while I cannot match users with a userPrincipalName of the form: username@whatever.domain ?</p>
  
  <p><em>NOTE 2:</em> I found the problem, not yet the solution. Actually, my search filter is perfectly fine and Spring Security is using it correctly. The problem is the authentication is performed by a bind to the AD server and to bind to the server I must use username@fsapps.company.com (if authorized) or either username@domain.in.constructor.arg.1. The sAMAccountName attribute is checked against a username with a domain rather than a username without a domain. If the domain is added, there is no sAMAccountName matching the value passed as an argument.</p>