1616
1717package org .springframework .security .ldap .authentication .ad ;
1818
19+ import java .text .MessageFormat ;
1920import java .util .Collections ;
2021import java .util .Hashtable ;
2122
6061 * @author Luke Taylor
6162 * @author Rob Winch
6263 * @author Gengwu Zhao
64+ * @author Andrey Litvitski
6365 */
6466public class ActiveDirectoryLdapAuthenticationProviderTests {
6567
@@ -95,9 +97,11 @@ public void successfulAuthenticationProducesExpectedAuthorities() throws Excepti
9597 @ Test
9698 public void customSearchFilterIsUsedForSuccessfulAuthentication () throws Exception {
9799 String customSearchFilter = "(&(objectClass=user)(sAMAccountName={0}))" ;
100+ String domain = "mydomain.eu" ;
101+ String encoded = MessageFormat .format (customSearchFilter , this .joe .getPrincipal () + "@" + domain );
98102 DirContextAdapter dca = new DirContextAdapter ();
99103 SearchResult sr = new SearchResult ("CN=Joe Jannsen,CN=Users" , dca , dca .getAttributes ());
100- given (this .ctx .search (any (Name .class ), eq (customSearchFilter ), any ( Object []. class ), any (SearchControls .class )))
104+ given (this .ctx .search (any (Name .class ), eq (encoded ), any (SearchControls .class )))
101105 .willReturn (new MockNamingEnumeration (sr ));
102106 ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider (
103107 "mydomain.eu" , "ldap://192.168.1.200/" );
@@ -109,34 +113,35 @@ public void customSearchFilterIsUsedForSuccessfulAuthentication() throws Excepti
109113
110114 @ Test
111115 public void defaultSearchFilter () throws Exception {
112- final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))" ;
116+ String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))" ;
117+ String domain = "mydomain.eu" ;
118+ String encoded = MessageFormat .format (defaultSearchFilter , this .joe .getPrincipal () + "@" + domain );
113119 DirContextAdapter dca = new DirContextAdapter ();
114120 SearchResult sr = new SearchResult ("CN=Joe Jannsen,CN=Users" , dca , dca .getAttributes ());
115- given (this .ctx .search (any (Name .class ), eq (defaultSearchFilter ), any ( Object []. class ), any (SearchControls .class )))
121+ given (this .ctx .search (any (Name .class ), eq (encoded ), any (SearchControls .class )))
116122 .willReturn (new MockNamingEnumeration (sr ));
117123 ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider (
118124 "mydomain.eu" , "ldap://192.168.1.200/" );
119125 customProvider .contextFactory = createContextFactoryReturning (this .ctx );
120126 Authentication result = customProvider .authenticate (this .joe );
121127 assertThat (result .isAuthenticated ()).isTrue ();
122- verify (this .ctx ).search (any (Name .class ), eq (defaultSearchFilter ), any (Object [].class ),
123- any (SearchControls .class ));
128+ verify (this .ctx ).search (any (Name .class ), any (String .class ), any (SearchControls .class ));
124129 }
125130
126131 // SEC-2897,SEC-2224
127132 @ Test
128133 public void bindPrincipalAndUsernameUsed () throws Exception {
129- final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0} ))" ;
130- ArgumentCaptor <Object [] > captor = ArgumentCaptor .forClass (Object [] .class );
134+ final String captureValue = "(&(objectClass=user)(userPrincipalName=joe@mydomain.eu ))" ;
135+ ArgumentCaptor <String > captor = ArgumentCaptor .forClass (String .class );
131136 DirContextAdapter dca = new DirContextAdapter ();
132137 SearchResult sr = new SearchResult ("CN=Joe Jannsen,CN=Users" , dca , dca .getAttributes ());
133- given (this .ctx .search (any (Name .class ), eq ( defaultSearchFilter ), captor .capture (), any (SearchControls .class )))
138+ given (this .ctx .search (any (Name .class ), captor .capture (), any (SearchControls .class )))
134139 .willReturn (new MockNamingEnumeration (sr ));
135140 ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider (
136141 "mydomain.eu" , "ldap://192.168.1.200/" );
137142 customProvider .contextFactory = createContextFactoryReturning (this .ctx );
138143 Authentication result = customProvider .authenticate (this .joe );
139- assertThat (captor .getValue ()).containsExactly ( "joe@mydomain.eu" , "joe" );
144+ assertThat (captor .getValue ()).isEqualTo ( captureValue );
140145 assertThat (result .isAuthenticated ()).isTrue ();
141146 }
142147
@@ -156,7 +161,7 @@ public void nullDomainIsSupportedIfAuthenticatingWithFullUserPrincipal() throws
156161 DirContextAdapter dca = new DirContextAdapter ();
157162 SearchResult sr = new SearchResult ("CN=Joe Jannsen,CN=Users" , dca , dca .getAttributes ());
158163 given (this .ctx .search (eq (LdapNameBuilder .newInstance ("DC=mydomain,DC=eu" ).build ()), any (String .class ),
159- any (Object []. class ), any ( SearchControls .class )))
164+ any (SearchControls .class )))
160165 .willReturn (new MockNamingEnumeration (sr ));
161166 this .provider .contextFactory = createContextFactoryReturning (this .ctx );
162167 assertThatExceptionOfType (BadCredentialsException .class ).isThrownBy (() -> this .provider .authenticate (this .joe ));
@@ -165,7 +170,7 @@ public void nullDomainIsSupportedIfAuthenticatingWithFullUserPrincipal() throws
165170
166171 @ Test
167172 public void failedUserSearchCausesBadCredentials () throws Exception {
168- given (this .ctx .search (any (Name .class ), any (String .class ), any (Object []. class ), any ( SearchControls .class )))
173+ given (this .ctx .search (any (Name .class ), any (String .class ), any (SearchControls .class )))
169174 .willThrow (new NameNotFoundException ());
170175 this .provider .contextFactory = createContextFactoryReturning (this .ctx );
171176 assertThatExceptionOfType (BadCredentialsException .class ).isThrownBy (() -> this .provider .authenticate (this .joe ));
@@ -174,7 +179,7 @@ public void failedUserSearchCausesBadCredentials() throws Exception {
174179 // SEC-2017
175180 @ Test
176181 public void noUserSearchCausesUsernameNotFound () throws Exception {
177- given (this .ctx .search (any (Name .class ), any (String .class ), any (Object []. class ), any ( SearchControls .class )))
182+ given (this .ctx .search (any (Name .class ), any (String .class ), any (SearchControls .class )))
178183 .willReturn (new MockNamingEnumeration (null ));
179184 this .provider .contextFactory = createContextFactoryReturning (this .ctx );
180185 assertThatExceptionOfType (BadCredentialsException .class ).isThrownBy (() -> this .provider .authenticate (this .joe ));
@@ -195,8 +200,7 @@ public void duplicateUserSearchCausesError() throws Exception {
195200 SearchResult searchResult = mock (SearchResult .class );
196201 given (searchResult .getObject ()).willReturn (new DirContextAdapter ("ou=1" ), new DirContextAdapter ("ou=2" ));
197202 given (searchResults .next ()).willReturn (searchResult );
198- given (this .ctx .search (any (Name .class ), any (String .class ), any (Object [].class ), any (SearchControls .class )))
199- .willReturn (searchResults );
203+ given (this .ctx .search (any (Name .class ), any (String .class ), any (SearchControls .class ))).willReturn (searchResults );
200204 this .provider .contextFactory = createContextFactoryReturning (this .ctx );
201205 assertThatExceptionOfType (IncorrectResultSizeDataAccessException .class )
202206 .isThrownBy (() -> this .provider .authenticate (this .joe ));
@@ -353,7 +357,7 @@ private void checkAuthentication(String rootDn, ActiveDirectoryLdapAuthenticatio
353357 SearchResult sr = new SearchResult ("CN=Joe Jannsen,CN=Users" , dca , dca .getAttributes ());
354358 @ SuppressWarnings ("deprecation" )
355359 Name searchBaseDn = LdapNameBuilder .newInstance (rootDn ).build ();
356- given (this .ctx .search (eq (searchBaseDn ), any (String .class ), any (Object []. class ), any ( SearchControls .class )))
360+ given (this .ctx .search (eq (searchBaseDn ), any (String .class ), any (SearchControls .class )))
357361 .willReturn (new MockNamingEnumeration (sr ))
358362 .willReturn (new MockNamingEnumeration (sr ));
359363 provider .contextFactory = createContextFactoryReturning (this .ctx );
0 commit comments