Change ActiveDirectoryLdapAuthenticationProvider to use LdapClient#18627
Change ActiveDirectoryLdapAuthenticationProvider to use LdapClient#18627therepanic wants to merge 1 commit intospring-projects:mainfrom
ActiveDirectoryLdapAuthenticationProvider to use LdapClient#18627Conversation
...ringframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java
Show resolved
Hide resolved
| } | ||
| catch (org.springframework.ldap.NamingException ex) { | ||
| throw badCredentials(ex); | ||
| } |
There was a problem hiding this comment.
This is what you should do, otherwise the tests will fail.
There was a problem hiding this comment.
I think the reason is because SpringSecurityLdapTemplate propagates the javax.naming exception while LdapClient wraps them. For passivity reasons, let's do something closer to:
if (ex.getCause() instanceof NamingException original) {
throw original;
}
throw badCredentials(ex);In this way, the original naming exception is propagated like it was before.
| given(this.ctx.search(any(Name.class), eq(customSearchFilter), any(Object[].class), any(SearchControls.class))) | ||
| given(this.ctx.search(any(Name.class), any(String.class), any(SearchControls.class))) |
There was a problem hiding this comment.
I'm not entirely sure whether this is a breaking change or not. Because when switching to LdapClient, we don't accept any(Object[].class) as the fourth argument, so we don't need to mock it.
There was a problem hiding this comment.
I think this is okay, though I'd recommend that we still use eq to test the filter so that the expectations are still the same level of specificity:
String customSearchFilter = "(&(objectClass=user)(sAMAccountName={0}))";
String domain = "mydomain.eu";
String encoded = MessageFormat.format(customSearchFilter, this.joe.getPrincipal() + "@" + domain);
...
given(this.ctx.search(any(Name.class), eq(encoded), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
...|
I don't quite understand whether this is breaking Change or not, please take a look at #18627 (comment) |
|
FYI I rebased based off origin/main |
Replaces SpringSecurityLdapTemplate with LdapClient for user search operations. Closes: spring-projectsgh-17291 Signed-off-by: Andrey Litvitski <andrey1010102008@gmail.com>
jzheaux
left a comment
There was a problem hiding this comment.
Thanks for the PR, @therepanic! I've left some feedback inline.
| given(this.ctx.search(any(Name.class), eq(customSearchFilter), any(Object[].class), any(SearchControls.class))) | ||
| given(this.ctx.search(any(Name.class), any(String.class), any(SearchControls.class))) |
There was a problem hiding this comment.
I think this is okay, though I'd recommend that we still use eq to test the filter so that the expectations are still the same level of specificity:
String customSearchFilter = "(&(objectClass=user)(sAMAccountName={0}))";
String domain = "mydomain.eu";
String encoded = MessageFormat.format(customSearchFilter, this.joe.getPrincipal() + "@" + domain);
...
given(this.ctx.search(any(Name.class), eq(encoded), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
...| } | ||
| catch (org.springframework.ldap.NamingException ex) { | ||
| throw badCredentials(ex); | ||
| } |
There was a problem hiding this comment.
I think the reason is because SpringSecurityLdapTemplate propagates the javax.naming exception while LdapClient wraps them. For passivity reasons, let's do something closer to:
if (ex.getCause() instanceof NamingException original) {
throw original;
}
throw badCredentials(ex);In this way, the original naming exception is propagated like it was before.
| .searchScope(SearchScope.SUBTREE) | ||
| .filter(this.searchFilter, bindPrincipal, username)) | ||
| .toEntry(); | ||
| if (result == null) { |
There was a problem hiding this comment.
This seems like something we should consider as an enhancement to LdapClient; a way to indicate that no results is an error. Will you please file an issue?
| try { | ||
| return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context, searchControls, searchRoot, | ||
| this.searchFilter, new Object[] { bindPrincipal, username }); | ||
| DirContextOperations result = ldapClient.search() |
There was a problem hiding this comment.
This might be slightly more readable as:
LdapQuery query = LdapQueryBuilder.query()
.base(searchRoot)
.searchScope(SearchScope.SUBTREE)
.filter(this.searchFilter, bindPrincipal, username);
DirContextOperations result = ldapClient.search().query(query).toEntry();
Replaces
SpringSecurityLdapTemplatewithLdapClientfor user search operations.Closes: gh-17291