0

My backend is a Spring Boot application and on the frontend I am using Angular.

I want to achieve the following authentication process:

  1. Use SSO with the Windows credentials using Kerberos/Spnego
  2. Some users are not included in LDAP and can't be authenticated with SSO. These users are created by other users and stored in a Postgres database and should be able to authenticate via username/password.
  3. If the user is currently not in the VPN/domain (and therefore SSO is not working) the user should also be able to authenticate via username/password with LDAP verificiation in the backend.

I was able to achieve SSO and also authentication via username+password. However, I do not know how to combine these two approaches and use the authentication via username+password as a fallback.

This is my current SecurityConfig:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    KerberosAuthenticationProvider kerberosAuthenticationProvider = spnegoConfig.kerberosAuthenticationProvider();
    KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider = spnegoConfig.kerberosServiceAuthenticationProvider();
    ProviderManager providerManager = new ProviderManager(kerberosAuthenticationProvider, kerberosServiceAuthenticationProvider);

    http
            .exceptionHandling()
            .authenticationEntryPoint(spnegoConfig.spnegoEntryPoint())
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .cors(cors -> cors.configurationSource(corsConfigurationSource()))
            .httpBasic(withDefaults())
            .authorizeHttpRequests((authRegistry) ->
                    authRegistry
                            .antMatchers("/index.html", "/", "/login").permitAll()
                            .anyRequest().authenticated()
            )
            // TODO: chaining of authenticationProviders do not work with SSO
            .authenticationProvider(kerberosAuthenticationProvider)
            .authenticationProvider(kerberosServiceAuthenticationProvider)
            .authenticationProvider(customDaoAuthenticationProvider)
            .authenticationProvider(customLdapAuthenticationProvider)
            .addFilterBefore(spnegoConfig.spnegoAuthenticationProcessingFilter(providerManager),
                    BasicAuthenticationFilter.class)
            .logout()
            .permitAll()
            .and()
            .csrf().disable();
    return http.build();
}

This is my SpnegoConfig:

@Configuration
@RequiredArgsConstructor
public class SpnegoConfig {

@Value("${servicePrincipal}")
private String servicePrincipal;

@Value("${keyTabLocation}")
private String keyTabLocation;

private final CustomLdapUserDetailsService customLdapUserDetailsService;

public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
    SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
    filter.setAuthenticationManager(authenticationManager);
    return filter;
}

@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
    KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
    SunJaasKerberosClient client = new SunJaasKerberosClient();
    provider.setKerberosClient(client);
    provider.setUserDetailsService(customLdapUserDetailsService);
    return provider;
}

@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
    KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
    provider.setTicketValidator(sunJaasKerberosTicketValidator());
    provider.setUserDetailsService(customLdapUserDetailsService);
    return provider;
}

@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
    SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
    ticketValidator.setServicePrincipal(servicePrincipal);
    ticketValidator.setKeyTabLocation(new ClassPathResource(keyTabLocation));
    return ticketValidator;
}

@Bean
public SpnegoEntryPoint spnegoEntryPoint() {
    return new SpnegoEntryPoint();
}

}
Steve2Fish
  • 187
  • 4
  • 15

0 Answers0