< /ul>
Die Anwendung hat sowohl lokale Benutzer -Authentifizierung als auch LDAP -Authentifizierung. Ich könnte alle Routen in meiner Anwendung konfigurieren. SecurityWebfilterchain anstelle von SecurityFilterChain. Authentifizierung. < /P>
Code: Select all
@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>
Dies funktioniert jedoch nicht. Ich habe mehrere LDAP -Testfälle gemacht, um dies zu debuggen. Verbindung zu LDAP, Suche und Authentifizierung. v3839] < /p>
< /blockquote>
Diese Testfälle, die ich erstellt habe, verwendet direkt entweder die ldapcontextSource, ldaptemplate, filterbasedDapusSearch oder initiDircontext. />
Vielleicht, weil LDAPAuthenticationManager nicht die Webflux -Reaktive unterstützt? Das Wickeln in ReactiveAuthenticationManagerAdapter funktioniert jedoch nicht.@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>
Jetzt habe ich eine Problemumgehung, die funktioniert, aber ich hasse es. Es ist zu ausführlich und zu viel Kesselplatte. migriert) < /p>
logging:
level:
com.company.goods: debug
org.springframework.cloud.gateway: debug
org.springframework.web: debug
org.springframework.security: trace
org.springframework.security.authentication: trace
org.springframework.security.ldap: trace
org.springframework.security.ldap.SpringSecurityLdapTemplate: trace
org.springframework.security.ldap.authentication: trace
org.springframework.security.ldap.authentication.LdapAuthenticationProvider: trace
org.springframework.ldap: trace
org.springframework.ldap.core: trace
org.springframework.ldap.core.support: trace
com.sun.jndi: DEBUG
javax.naming: DEBUG
< /code>
Beim Ausführen der alten Anwendung erhalte ich diese Protokollierung bei der Authentifizierung mit LDAP ON /API /Login. Benutzerdaten und Unternehmensdaten wurden saniert. < /P>
DEBUG o.s.security.web.FilterChainProxy - /auth/login at position 5 of 12 in additional filter chain; firing Filter: 'JWTLoginFilter'
DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/auth/login'; against '/auth/login'
DEBUG n.t.r.l.auth.security.JWTLoginFilter - Request is to process authentication
DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
DEBUG o.s.s.a.d.DaoAuthenticationProvider - User 'myuser' not found
DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
DEBUG o.s.s.a.d.DaoAuthenticationProvider - User 'myuser' not found
DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
DEBUG o.s.s.l.a.LdapAuthenticationProvider - Processing authentication request for user: myuser
DEBUG o.s.s.l.s.FilterBasedLdapUserSearch - Searching for user 'myuser', with user search [ searchFilter: '(sAMAccountName={0})', searchBase: 'DC=company,DC=com', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldap://adldap.company.com:389'
DEBUG o.s.s.l.SpringSecurityLdapTemplate - Searching for entry under DN '', base = 'dc=company,dc=no', filter = '(sAMAccountName={0})'
DEBUG o.s.s.l.SpringSecurityLdapTemplate - Found DN: CN=My Name (myuser),OU=Users,OU=CompanyGroup,OU=CompanyGroup_A,DC=company,DC=com
DEBUG o.s.s.l.a.BindAuthenticator - Attempting to bind as cn=My Name (myuser),ou=Users,ou=CompanyGroup,ou=CompanyGroup_A,dc=company,dc=no
DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldap://adldap.company.com:389'
DEBUG o.s.s.l.a.BindAuthenticator - Retrieving attributes...
DEBUG o.s.s.l.u.DefaultLdapAuthoritiesPopulator - Getting authorities for user cn=My Name (myuser),ou=Users,ou=CompanyGroup,ou=CompanyGroup_A,dc=company,dc=no
DEBUG o.s.s.l.u.DefaultLdapAuthoritiesPopulator - Searching for roles for user 'myuser', DN = 'cn=My Name (myuser),ou=Users,ou=CompanyGroup,ou=CompanyGroup_A,dc=company,dc=com', with filter (member={0}) in search base 'OU=SecurityGroups,OU=Cloud Objects,DC=company,DC=com'
DEBUG o.s.s.l.SpringSecurityLdapTemplate - Using filter: (member=cn=My Name \28myuser\29,ou=Users,ou=CompanyGroup,ou=CompanyGroup_A,dc=company,dc=no)
DEBUG o.s.ldap.core.LdapTemplate - The returnObjFlag of supplied SearchControls is not set but a ContextMapper is used - setting flag to true
DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldap://adldap.company.com:389'
DEBUG o.s.s.l.u.DefaultLdapAuthoritiesPopulator - Roles from search: [{spring.security.ldap.dn=[CN=CompanyConsultants,OU=SecurityGroups,OU=Cloud Objects,DC=company,DC=com], cn=[CompanyConsultants]}]
DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@757b1109
< /code>
Beim Ausführen der migrierten Anwendung und des Aufrufens /API /Login erhalte ich dieses Protokoll. < /p>
TRACE 19588 --- [lrm-auth-service] [oundedElastic-1] o.s.s.authentication.ProviderManager : Authenticating request with LdapAuthenticationProvider (1/1)
DEBUG 19588 --- [lrm-auth-service] [oundedElastic-1] o.s.s.l.a.BindAuthenticator : Failed to bind with any user DNs []
TRACE 19588 --- [lrm-auth-service] [oundedElastic-1] o.s.s.l.a.BindAuthenticator : Searching for user using FilterBasedLdapUserSearch [searchFilter=(sAMAccountName={0}); searchBase=DC=company,DC=com; scope=subtree; searchTimeLimit=0; derefLinkFlag=false ]
TRACE 19588 --- [lrm-auth-service] [oundedElastic-1] o.s.s.l.s.FilterBasedLdapUserSearch : Searching for user 'myuser', with FilterBasedLdapUserSearch [searchFilter=(sAMAccountName={0}); searchBase=DC=company,DC=com; scope=subtree; searchTimeLimit=0; derefLinkFlag=false ]
WARN 19588 --- [lrm-auth-service] [oundedElastic-1] n.t.goods.service.auth.web.AuthController : Authentication failed for user myuser
org.springframework.security.authentication.InternalAuthenticationServiceException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09044A, comment: AcceptSecurityContext error, data 52e, v3839]
at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:190) ~[spring-security-ldap-6.4.2.jar:6.4.2]
at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:80) ~[spring-security-ldap-6.4.2.jar:6.4.2]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.4.2.jar:6.4.2]
at org.springframework.security.authentication.ReactiveAuthenticationManagerAdapter.doAuthenticate(ReactiveAuthenticationManagerAdapter.java:60) ~[spring-security-core-6.4.2.jar:6.4.2]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:132) ~[reactor-core-3.7.2.jar:3.7.2]
at reactor.core.publisher.FluxSubscribeOnValue$ScheduledScalar.run(FluxSubscribeOnValue.java:181) ~[reactor-core-3.7.2.jar:3.7.2]
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) ~[reactor-core-3.7.2.jar:3.7.2]
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) ~[reactor-core-3.7.2.jar:3.7.2]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
Caused by: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09044A, comment: AcceptSecurityContext error, data 52e, v3839]
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:193) ~[spring-ldap-core-3.2.10.jar:3.2.10]
at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:362) ~[spring-ldap-core-3.2.10.jar:3.2.10]
at org.springframework.ldap.core.support.AbstractContextSource.doGetContext(AbstractContextSource.java:148) ~[spring-ldap-core-3.2.10.jar:3.2.10]
at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:168) ~[spring-ldap-core-3.2.10.jar:3.2.10]
at org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:789) ~[spring-ldap-core-3.2.10.jar:3.2.10]
at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntry(SpringSecurityLdapTemplate.java:261) ~[spring-security-ldap-6.4.2.jar:6.4.2]
at org.springframework.security.ldap.search.FilterBasedLdapUserSearch.searchForUser(FilterBasedLdapUserSearch.java:100) ~[spring-security-ldap-6.4.2.jar:6.4.2]
at org.springframework.security.ldap.authentication.BindAuthenticator.authenticate(BindAuthenticator.java:88) ~[spring-security-ldap-6.4.2.jar:6.4.2]
at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:174) ~[spring-security-ldap-6.4.2.jar:6.4.2]
... 12 common frames omitted
Caused by: javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09044A, comment: AcceptSecurityContext error, data 52e, v3839]
at java.naming/com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3260) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3206) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2992) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2906) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtx.(LdapCtx.java:349) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxFromUrl(LdapCtxFactory.java:229) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:189) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:247) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154) ~[na:na]
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84) ~[na:na]
at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:520) ~[na:na]
at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305) ~[na:na]
at java.naming/javax.naming.InitialContext.init(InitialContext.java:236) ~[na:na]
at java.naming/javax.naming.ldap.InitialLdapContext.(InitialLdapContext.java:154) ~[na:na]
at org.springframework.ldap.core.support.LdapContextSource.getDirContextInstance(LdapContextSource.java:44) ~[spring-ldap-core-3.2.10.jar:3.2.10]
at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:350) ~[spring-ldap-core-3.2.10.jar:3.2.10]
... 19 common frames omitted
< /code>
Versuchs Vorschläge von M.Deinum
1.
ldapContextSource.setCacheEnvironmentProperties(false);
< /code>
< /li>
< /ol>
final var authenticationManager = factory.createAuthenticationManager();
final var adapter = new ReactiveAuthenticationManagerAdapter(authenticationManager);
adapter.setScheduler(Schedulers.immediate());
return adapter;