В настоящее время я пытаюсь разработать приложение Spring Boot, целью которого будет управление записями пользователей в нашем каталоге LDAP.
Логин LDAP уже работает; так же как и поиск групп, членом которых является пользователь.
Кроме того, я хотел бы заполнить объект Spring Security Principal еще некоторыми атрибутами LDAP этого пользователя. Я прочитал несколько сообщений о SO, а также официальную документацию Spring, но просто не могу заставить это работать.
Вот мой текущий код: Класс AuthenticationConfiguration
@Configuration
class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
private String ldapUrl = "ldap://127.0.0.1:10389/dc=corp,dc=org";
private String bindUser = "cn=spring,ou=users,dc=corp,dc=org";
private String bindPW = "<password>";
private String groupSearchBase = "ou=groups";
private String groupSearchFilter = "(member={0})";
private String userDnPattern = "uid={0},ou=users";
private Log log = LogFactory.getLog(this.getClass());
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapUrl);
contextSource.setUserDn(bindUser);
contextSource.setPassword(bindPW);
contextSource.afterPropertiesSet();
log.info(contextSource.getReadOnlyContext().getAttributes("uid=testuser,ou=users")); // returns all LDAP attributes from that user
DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(contextSource, groupSearchBase);
populator.setGroupSearchFilter(groupSearchFilter);
populator.setSearchSubtree(true);
populator.setIgnorePartialResultException(true);
auth
.ldapAuthentication()
.ldapAuthoritiesPopulator(populator)
.contextSource(contextSource)
.userDetailsContextMapper(userDetailsContextMapper())
.userDnPatterns(userDnPattern)
;
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new CustomUserDetailsContextMapper();
}
}
Как видите, я использую метод userDetailsContextMapper() для возврата экземпляра моего CustomUserDetailsContextMapper:
@Configuration
public class CustomUserDetailsContextMapper extends LdapUserDetailsMapper implements UserDetailsContextMapper {
private Log log = LogFactory.getLog(this.getClass());
@Override
public LdapUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
LdapUserDetailsImpl details = (LdapUserDetailsImpl) super.mapUserFromContext(ctx, username, authorities);
log.info("DN from ctx: " + ctx.getDn()); // return correct DN
log.info("Attributes size: " + ctx.getAttributes().size()); // always returns 0
return new CustomUserDetails(details);
}
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
// default
}
}
Теперь, когда вы посмотрите на этот первый оператор журнала в AuthenticationConfiguration, Spring фактически выведет весь пользовательский объект на стандартный вывод, правильно показывая все атрибуты LDAP от пользователя:
{displayname=displayName: Test User, givenname=givenName: Test, objectclass=objectClass: posixAccount, top [...]}
Однако операторы журнала в моем классе CustomUserDetailsContextMapper этого не делают. Хотя первый правильно отображает DN вошедшего в систему пользователя, второй просто отображает 0, т.е. ctx не содержит никаких атрибутов текущего пользователя.
Я также пытался запросить атрибуты напрямую через ctx.getAttribute("attribute"), ctx.getStringAttribute("attribute") или ctx.getObjectAttribute("attribute"), но безрезультатно.
Как получить доступ к атрибутам LDAP из метода mapUserFromContext?
У меня действительно нет идей, поэтому любая помощь будет принята с благодарностью :-)