Skip to content

Commit 7643202

Browse files
dadikovirwinch
authored andcommitted
ActiveDirectoryLdapAuthenticationProvider uses InternalAuthenticationServiceException
Closes gh-2884
1 parent 0d0afb9 commit 7643202

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

core/src/main/resources/org/springframework/security/messages.properties

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ DigestAuthenticationFilter.usernameNotFound=Username {0} not found
3131
JdbcDaoImpl.noAuthority=User {0} has no GrantedAuthority
3232
JdbcDaoImpl.notFound=User {0} not found
3333
LdapAuthenticationProvider.badCredentials=Bad credentials
34+
LdapAuthenticationProvider.badLdapConnection=Connection to LDAP server failed
3435
LdapAuthenticationProvider.credentialsExpired=User credentials have expired
3536
LdapAuthenticationProvider.disabled=User is disabled
3637
LdapAuthenticationProvider.expired=User account has expired

ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java

+17-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.security.ldap.authentication.ad;
1717

1818
import org.springframework.dao.IncorrectResultSizeDataAccessException;
19+
import org.springframework.ldap.CommunicationException;
1920
import org.springframework.ldap.core.DirContextOperations;
2021
import org.springframework.ldap.core.DistinguishedName;
2122
import org.springframework.ldap.core.support.DefaultDirObjectFactory;
@@ -24,6 +25,7 @@
2425
import org.springframework.security.authentication.BadCredentialsException;
2526
import org.springframework.security.authentication.CredentialsExpiredException;
2627
import org.springframework.security.authentication.DisabledException;
28+
import org.springframework.security.authentication.InternalAuthenticationServiceException;
2729
import org.springframework.security.authentication.LockedException;
2830
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
2931
import org.springframework.security.core.GrantedAuthority;
@@ -140,12 +142,15 @@ protected DirContextOperations doAuthentication(
140142
UsernamePasswordAuthenticationToken auth) {
141143
String username = auth.getName();
142144
String password = (String) auth.getCredentials();
143-
144-
DirContext ctx = bindAsUser(username, password);
145+
DirContext ctx = null;
145146

146147
try {
148+
ctx = bindAsUser(username, password);
147149
return searchForUser(ctx, username);
148150
}
151+
catch (CommunicationException e) {
152+
throw badLdapConnection(e);
153+
}
149154
catch (NamingException e) {
150155
logger.error("Failed to locate directory entry for authenticated user: "
151156
+ username, e);
@@ -207,8 +212,7 @@ private DirContext bindAsUser(String username, String password) {
207212
|| (e instanceof OperationNotSupportedException)) {
208213
handleBindException(bindPrincipal, e);
209214
throw badCredentials(e);
210-
}
211-
else {
215+
} else {
212216
throw LdapUtils.convertLdapException(e);
213217
}
214218
}
@@ -300,6 +304,12 @@ private BadCredentialsException badCredentials(Throwable cause) {
300304
return (BadCredentialsException) badCredentials().initCause(cause);
301305
}
302306

307+
private InternalAuthenticationServiceException badLdapConnection(Throwable cause) {
308+
return new InternalAuthenticationServiceException(messages.getMessage(
309+
"LdapAuthenticationProvider.badLdapConnection",
310+
"Connection to LDAP server failed."), cause);
311+
}
312+
303313
private DirContextOperations searchForUser(DirContext context, String username)
304314
throws NamingException {
305315
SearchControls searchControls = new SearchControls();
@@ -314,6 +324,9 @@ private DirContextOperations searchForUser(DirContext context, String username)
314324
searchControls, searchRoot, searchFilter,
315325
new Object[] { bindPrincipal, username });
316326
}
327+
catch (CommunicationException ldapCommunicationException) {
328+
throw badLdapConnection(ldapCommunicationException);
329+
}
317330
catch (IncorrectResultSizeDataAccessException incorrectResults) {
318331
// Search should never return multiple results if properly configured - just
319332
// rethrow

ldap/src/test/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProviderTests.java

+22-6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.security.authentication.BadCredentialsException;
3333
import org.springframework.security.authentication.CredentialsExpiredException;
3434
import org.springframework.security.authentication.DisabledException;
35+
import org.springframework.security.authentication.InternalAuthenticationServiceException;
3536
import org.springframework.security.authentication.LockedException;
3637
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
3738
import org.springframework.security.core.Authentication;
@@ -58,6 +59,9 @@
5859
* @author Rob Winch
5960
*/
6061
public class ActiveDirectoryLdapAuthenticationProviderTests {
62+
public static final String EXISTING_LDAP_PROVIDER = "ldap://192.168.1.200/";
63+
public static final String NON_EXISTING_LDAP_PROVIDER = "ldap://192.168.1.201/";
64+
6165
@Rule
6266
public ExpectedException thrown = ExpectedException.none();
6367

@@ -378,17 +382,29 @@ public void errorWithNoSubcodeIsHandledCleanly() throws Exception {
378382
}
379383

380384
@Test(expected = org.springframework.ldap.CommunicationException.class)
381-
public void nonAuthenticationExceptionIsConvertedToSpringLdapException()
382-
throws Exception {
383-
provider.contextFactory = createContextFactoryThrowing(new CommunicationException(
384-
msg));
385-
provider.authenticate(joe);
385+
public void nonAuthenticationExceptionIsConvertedToSpringLdapException() throws Throwable {
386+
try {
387+
provider.contextFactory = createContextFactoryThrowing(new CommunicationException(
388+
msg));
389+
provider.authenticate(joe);
390+
} catch (InternalAuthenticationServiceException e) {
391+
// Since GH-8418 ldap communication exception is wrapped into InternalAuthenticationServiceException.
392+
// This test is about the wrapped exception, so we throw it.
393+
throw e.getCause();
394+
}
395+
}
396+
397+
@Test(expected = org.springframework.security.authentication.InternalAuthenticationServiceException.class )
398+
public void connectionExceptionIsWrappedInInternalException() throws Exception {
399+
ActiveDirectoryLdapAuthenticationProvider noneReachableProvider = new ActiveDirectoryLdapAuthenticationProvider(
400+
"mydomain.eu", NON_EXISTING_LDAP_PROVIDER, "dc=ad,dc=eu,dc=mydomain");
401+
noneReachableProvider.doAuthentication(joe);
386402
}
387403

388404
@Test
389405
public void rootDnProvidedSeparatelyFromDomainAlsoWorks() throws Exception {
390406
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
391-
"mydomain.eu", "ldap://192.168.1.200/", "dc=ad,dc=eu,dc=mydomain");
407+
"mydomain.eu", EXISTING_LDAP_PROVIDER, "dc=ad,dc=eu,dc=mydomain");
392408
checkAuthentication("dc=ad,dc=eu,dc=mydomain", provider);
393409

394410
}

0 commit comments

Comments
 (0)