Обновлено приложение для Spring Boot. < /p>
Java 11> Java 21 < /li>
Spring Boot 2.3.3> 3.4.4 < /li>
Spring Zuul> Spring Cloud Gateway < /li>
Hystrix Fall Back> Resiliance4 < /li>
Sepringse Fall Back> REILAININIARS4 Ldap < /li>
< /ul>
Приложение имеет как аутентификацию локальных пользователей, так и аутентификацию LDAP. Gateway Я мог бы настроить все маршруты в моем Application.yml < /p>
Однако это означало, что мне пришлось настроить реактивную пружину. SecurityWebFilterChain вместо безопасности. Аутентификация. < /P>
@Bean(name = "authenticationManager")
public ReactiveAuthenticationManager authenticationManager(
final ReactiveUserDetailsService userDetailsService,
final ReactiveAuthenticationManager ldapAuthenticationManager
) {
final List managers = new ArrayList();
if (ldapEnabled) {
managers.add(ldapAuthenticationManager);
}
managers.add(new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService) {{
setPasswordEncoder(passwordEncoder);
}});
return new DelegatingReactiveAuthenticationManager(managers);
}
@Bean(name = "ldapAuthenticationManager")
public ReactiveAuthenticationManager ldapAuthenticationManager(
final LdapContextSource ldapContextSource,
final UserDetailsContextMapperImpl userDetailsContextMapper,
final LdapAuthoritiesPopulator ldapAuthoritiesPopulator
) {
final var factory = new LdapBindAuthenticationManagerFactory(ldapContextSource);
factory.setUserSearchBase(ldapUserSearchBase);
factory.setUserSearchFilter(ldapUserSearchFilter);
factory.setUserDetailsContextMapper(userDetailsContextMapper);
factory.setLdapAuthoritiesPopulator(ldapAuthoritiesPopulator);
final var authenticationManager = factory.createAuthenticationManager();
return new ReactiveAuthenticationManagerAdapter(authenticationManager);
}
@Bean
public LdapContextSource ldapContextSource() {
final var ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl(ldapUrl);
ldapContextSource.setUserDn(ldapBindDn);
ldapContextSource.setPassword(ldapBindPassword);
// Explicitly configure environment props
ldapContextSource.setBaseEnvironmentProperties(
Map.of(
"java.naming.referral", "follow",
"java.naming.security.authentication", "simple"
)
);
// Manually initialize the context
ldapContextSource.afterPropertiesSet();
return ldapContextSource;
}
< /code>
Однако это не работает. Я сделал несколько тестовых случаев LDAP, чтобы отлаживать это. Подключение к LDAP, поиск и аутентификацию.
Все они работают, но безопасность Spring Bind Bind Spring не работает. \ < /P>
[LDAP: код ошибки 49 - 80090308: LDAPERR: DSID -09044A, Комментарий: AgragingSecurityContectrectrectrectrectrectrectrectrectrectrectrecreer. v3839] < /p>
< /blockquote>
Эти тестовые примеры, которые я сделал, непосредственно использует либо LDAPContextSource, LDAptemplate, FilterBasedLdapuserSearch или initialDircontext. < /p>
Это просто эта LdapbindaUtnationAntaintaintaintaffectaffectaffect. /> Возможно, потому что ldapauthenticationManager не поддерживает реактивный Webflux? Охватывание его в ReactiveAuthenticationManagerAdapter, однако не работает.@Bean(name = "ldapAuthenticationManager")
public ReactiveAuthenticationManager ldapAuthenticationManager(
final LdapContextSource ldapContextSource
) {
return auth -> {
final var username = auth.getName();
final var password = auth.getCredentials().toString();
// UPN format username instead of DN
final var upn = username.contains("@") ? username : username + "@company.com";
return Mono.fromCallable(() -> {
// Step 1: Bind as the user
final var ctx = ldapContextSource.getContext(upn, password);
// Step 2: Search for user DN using bound context
final var sc = new SearchControls();
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
final var results = ctx.search(
ldapUserSearchBase,
ldapUserSearchFilter.replace("{0}", username),
sc
);
String userDn = null;
while (results.hasMore()) {
final var sr = results.next();
userDn = sr.getNameInNamespace();
break;
}
if (userDn == null) {
ctx.close();
throw new BadCredentialsException("User not found in LDAP");
}
// Step 3: Search for groups (authorities) using the bound user context
List authorities = new ArrayList();
NamingEnumeration groupResults = ctx.search(
ldapGroupSearchBase,
ldapGroupSearchFilter.replace("{0}", userDn),
sc
);
while (groupResults.hasMore()) {
final var group = groupResults.next();
final var cn = group.getAttributes().get("cn");
if (cn != null) {
final var role = cn.get().toString();
authorities.add(new SimpleGrantedAuthority(role));
}
}
ctx.close();
return new UsernamePasswordAuthenticationToken(username, password, authorities);
}).onErrorMap(e -> {
return new BadCredentialsException("LDAP authentication failed", e);
});
};
}
< /code>
Теперь у меня есть обходной путь, который работает, но я ненавижу его. Это слишком условно и слишком много шаблон.
Также как насчет моего пользователя.>
Подробнее здесь: https://stackoverflow.com/questions/795 ... bind-fails
Spring Boot Reactive с Webflux: безопасность с LDAP Bind Fail ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение