11package io .kafbat .ui .config .auth ;
22
33import io .kafbat .ui .service .rbac .AccessControlService ;
4+ import io .kafbat .ui .service .rbac .extractor .RbacActiveDirectoryAuthoritiesExtractor ;
45import io .kafbat .ui .service .rbac .extractor .RbacLdapAuthoritiesExtractor ;
56import io .kafbat .ui .util .StaticFileWebFilter ;
67import java .util .Collection ;
78import java .util .List ;
89import java .util .Optional ;
910import lombok .RequiredArgsConstructor ;
1011import lombok .extern .slf4j .Slf4j ;
12+ import org .springframework .beans .factory .annotation .Autowired ;
1113import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
1214import org .springframework .boot .context .properties .EnableConfigurationProperties ;
1315import org .springframework .context .ApplicationContext ;
1719import org .springframework .ldap .core .DirContextOperations ;
1820import org .springframework .ldap .core .support .BaseLdapPathContextSource ;
1921import org .springframework .ldap .core .support .LdapContextSource ;
20- import org .springframework .security .authentication .AuthenticationManager ;
2122import org .springframework .security .authentication .ProviderManager ;
2223import org .springframework .security .authentication .ReactiveAuthenticationManager ;
2324import org .springframework .security .authentication .ReactiveAuthenticationManagerAdapter ;
2930import org .springframework .security .ldap .authentication .AbstractLdapAuthenticationProvider ;
3031import org .springframework .security .ldap .authentication .BindAuthenticator ;
3132import org .springframework .security .ldap .authentication .LdapAuthenticationProvider ;
33+ import org .springframework .security .ldap .authentication .NullLdapAuthoritiesPopulator ;
3234import org .springframework .security .ldap .authentication .ad .ActiveDirectoryLdapAuthenticationProvider ;
35+ import org .springframework .security .ldap .authentication .ad .DefaultActiveDirectoryAuthoritiesPopulator ;
3336import org .springframework .security .ldap .search .FilterBasedLdapUserSearch ;
3437import org .springframework .security .ldap .search .LdapUserSearch ;
35- import org .springframework .security .ldap .userdetails .DefaultLdapAuthoritiesPopulator ;
3638import org .springframework .security .ldap .userdetails .LdapAuthoritiesPopulator ;
3739import org .springframework .security .ldap .userdetails .LdapUserDetailsMapper ;
3840import org .springframework .security .web .server .SecurityWebFilterChain ;
@@ -49,39 +51,51 @@ public class LdapSecurityConfig extends AbstractAuthSecurityConfig {
4951 private final LdapProperties props ;
5052
5153 @ Bean
52- public ReactiveAuthenticationManager authenticationManager (LdapContextSource ldapContextSource ,
53- LdapAuthoritiesPopulator authoritiesExtractor ,
54- AccessControlService acs ) {
54+ public ReactiveAuthenticationManager authenticationManager (AbstractLdapAuthenticationProvider authProvider ) {
55+ return new ReactiveAuthenticationManagerAdapter (new ProviderManager (List .of (authProvider )));
56+ }
57+
58+ @ Bean
59+ public AbstractLdapAuthenticationProvider authenticationProvider (LdapAuthoritiesPopulator authoritiesExtractor ,
60+ @ Autowired (required = false ) BindAuthenticator ba ,
61+ AccessControlService acs ) {
5562 var rbacEnabled = acs .isRbacEnabled ();
63+
64+ AbstractLdapAuthenticationProvider authProvider ;
65+
66+ if (!props .isActiveDirectory ()) {
67+ authProvider = new LdapAuthenticationProvider (ba , authoritiesExtractor );
68+ } else {
69+ authProvider = new ActiveDirectoryLdapAuthenticationProvider (props .getActiveDirectoryDomain (),
70+ props .getUrls ());
71+ authProvider .setUseAuthenticationRequestCredentials (true );
72+ ((ActiveDirectoryLdapAuthenticationProvider ) authProvider ).setAuthoritiesPopulator (authoritiesExtractor );
73+ }
74+
75+ if (rbacEnabled ) {
76+ authProvider .setUserDetailsContextMapper (new RbacUserDetailsMapper ());
77+ }
78+
79+ return authProvider ;
80+ }
81+
82+ @ Bean
83+ @ ConditionalOnProperty (value = "oauth2.ldap.activeDirectory" , havingValue = "false" )
84+ public BindAuthenticator ldapBindAuthentication (LdapContextSource ldapContextSource ) {
5685 BindAuthenticator ba = new BindAuthenticator (ldapContextSource );
86+
5787 if (props .getBase () != null ) {
5888 ba .setUserDnPatterns (new String [] {props .getBase ()});
5989 }
90+
6091 if (props .getUserFilterSearchFilter () != null ) {
6192 LdapUserSearch userSearch =
6293 new FilterBasedLdapUserSearch (props .getUserFilterSearchBase (), props .getUserFilterSearchFilter (),
6394 ldapContextSource );
6495 ba .setUserSearch (userSearch );
6596 }
6697
67- AbstractLdapAuthenticationProvider authenticationProvider ;
68- if (!props .isActiveDirectory ()) {
69- authenticationProvider = rbacEnabled
70- ? new LdapAuthenticationProvider (ba , authoritiesExtractor )
71- : new LdapAuthenticationProvider (ba );
72- } else {
73- authenticationProvider = new ActiveDirectoryLdapAuthenticationProvider (props .getActiveDirectoryDomain (),
74- props .getUrls ()); // TODO Issue #3741
75- authenticationProvider .setUseAuthenticationRequestCredentials (true );
76- }
77-
78- if (rbacEnabled ) {
79- authenticationProvider .setUserDetailsContextMapper (new UserDetailsMapper ());
80- }
81-
82- AuthenticationManager am = new ProviderManager (List .of (authenticationProvider ));
83-
84- return new ReactiveAuthenticationManagerAdapter (am );
98+ return ba ;
8599 }
86100
87101 @ Bean
@@ -95,24 +109,27 @@ public LdapContextSource ldapContextSource() {
95109 }
96110
97111 @ Bean
98- public DefaultLdapAuthoritiesPopulator ldapAuthoritiesExtractor (ApplicationContext context ,
99- BaseLdapPathContextSource contextSource ,
100- AccessControlService acs ) {
101- var rbacEnabled = acs != null && acs .isRbacEnabled ();
112+ public LdapAuthoritiesPopulator authoritiesExtractor (ApplicationContext ctx ,
113+ BaseLdapPathContextSource ldapCtx ,
114+ AccessControlService acs ) {
115+ if (!props .isActiveDirectory ()) {
116+ if (!acs .isRbacEnabled ()) {
117+ return new NullLdapAuthoritiesPopulator ();
118+ }
102119
103- DefaultLdapAuthoritiesPopulator extractor ;
120+ var extractor = new RbacLdapAuthoritiesExtractor ( ctx , ldapCtx , props . getGroupFilterSearchBase ()) ;
104121
105- if (rbacEnabled ) {
106- extractor = new RbacLdapAuthoritiesExtractor (context , contextSource , props .getGroupFilterSearchBase ());
122+ Optional .ofNullable (props .getGroupFilterSearchFilter ()).ifPresent (extractor ::setGroupSearchFilter );
123+ extractor .setRolePrefix ("" );
124+ extractor .setConvertToUpperCase (false );
125+ extractor .setSearchSubtree (true );
126+
127+ return extractor ;
107128 } else {
108- extractor = new DefaultLdapAuthoritiesPopulator (contextSource , props .getGroupFilterSearchBase ());
129+ return acs .isRbacEnabled ()
130+ ? new RbacActiveDirectoryAuthoritiesExtractor (ctx )
131+ : new DefaultActiveDirectoryAuthoritiesPopulator ();
109132 }
110-
111- Optional .ofNullable (props .getGroupFilterSearchFilter ()).ifPresent (extractor ::setGroupSearchFilter );
112- extractor .setRolePrefix ("" );
113- extractor .setConvertToUpperCase (false );
114- extractor .setSearchSubtree (true );
115- return extractor ;
116133 }
117134
118135 @ Bean
@@ -142,7 +159,7 @@ public SecurityWebFilterChain configureLdap(ServerHttpSecurity http) {
142159 return builder .build ();
143160 }
144161
145- private static class UserDetailsMapper extends LdapUserDetailsMapper {
162+ private static class RbacUserDetailsMapper extends LdapUserDetailsMapper {
146163 @ Override
147164 public UserDetails mapUserFromContext (DirContextOperations ctx , String username ,
148165 Collection <? extends GrantedAuthority > authorities ) {
0 commit comments