Expected Behavior
Class ActiveDirectoryLdapAuthenticationProvider
is non-final and can be extended
Current Behavior
Class ActiveDirectoryLdapAuthenticationProvider
is final and cannot be extended
Context
NOTE: I am aware of existence of these tickets: https://github.com/spring-projects/spring-security/issues/13844 https://github.com/spring-projects/spring-security/issues/3303
In our project ActiveDirectoryLdapAuthenticationProvider
is used for authenticating against Active Directory since it uses Active Directory configuration conventions which allows for binding using just UserPrincipalName or even sAMAccountName. However, we use it only for authenticating and do not care about user details at all (we have our own custom context mapper which does not uses it). The problem is that ActiveDirectoryLdapAuthenticationProvider.doAuthentication()
method is implemented as follows:
@Override
protected DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth) {
...
try {
ctx = bindAsUser(username, password);
return searchForUser(ctx, username);
}
...
which means it performs the search whether we need it or not and that forces us to correctly configure search filter even if we do not need it.
Here is a draft of copied and modified ActiveDirectoryLdapAuthenticationProvider
class which works for us:
@Override
protected DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth) {
String username = auth.getName();
String password = (String) auth.getCredentials();
DirContext ctx = null;
try {
ctx = bindAsUser(username, password);
// return searchForUser(ctx, username);
return createStubUser(username);
}
catch (CommunicationException ex) {
throw badLdapConnection(ex);
}
// catch (NamingException ex) {
// this.logger.error("Failed to locate directory entry for authenticated user: " + username, ex);
// throw badCredentials(ex);
// }
finally {
LdapUtils.closeContext(ctx);
}
}
private DirContextOperations createStubUser(String username) {
// Minimal placeholder user, Spring only requires a non-null object
return new DirContextAdapter() {{
setAttributeValue("userPrincipalName", username);
}};
}
To sum it up, making ActiveDirectoryLdapAuthenticationProvider
class non-final would allow us to cleanly do what we need instead of copying a code from spring classes.
There already is this ticket which was unfortunately closed due to different use case which was possible to solve by delegating: https://github.com/spring-projects/spring-security/issues/3303
And also there is this ticket which is migrated from somewhere else which mentions removing final
but the ticket itself was originated from a different use case which has already been resolved. This ticket has been open for a decade now so I suppose it's not active:
https://github.com/spring-projects/spring-security/issues/3303
Alternative approach could possibly be introducing ActiveDirectoryBindOnlyAuthenticationProvider
that would not perform search, just binding.
Any response or effort in this matter will be much appreciated, thanks!