authenticationManger method not present in spring security 6, Saml Config migration

634 views Asked by At

We are migrating our springboot application to springboot 3.x. In the latest version of springboot, i see the spring-security upgraded to version 6.

In this version WebSecurityConfigurerAdapter is removed.

I have a SamlConfiguation class written on spring-boot 2. x. I have to define SAMLWebSSOHoKProcessingFilter and SAMLProcessingFilter beans.

These beans use authenticationManager() method from WebSecurityConfigurerAdapter class.

How do I define them using spring security 6? i changed it to

@Bean
public AuthenticationManager authenticationManagerBean(AuthenticationConfiguration authConfiguration) throws Exception {
    return authConfiguration.getAuthenticationManager();
}

but when i start the application call any api, i get the error 10:20:55.995 ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/cms-service/webapi].[dispatcherServlet].log() @175 - Servlet.service() for servlet [dispatcherServlet] in context with path [/cms-service/webapi] threw exception [Filter execution threw an exception] with root cause java.lang.AbstractMethodError: Receiver class org.springframework.security.saml.metadata.MetadataGeneratorFilter does not define or inherit an implementation of the resolved method 'abstract void doFilter(jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse, jakarta.servlet.FilterChain)' of interface jakarta.servlet.Filter. at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227) at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137) at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)

here is my complete SAMLSecurityConfig

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = {SAMLUserDetailsServiceImpl.class, Environment.class, SAMLConfig.class})
@Order(2)
public class SAMLSecurityConfig {

private static final Logger LOGGER = LoggerFactory.getLogger(SAMLSecurityConfig.class);

private static final String LOGIN = "/login";

private final SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl;

private final Environment environment;

private Timer backgroundTaskTimer;

private MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager;

private ApplicationEventPublisher applicationEventPublisher;
private  AuthenticationConfiguration authenticationConfiguration;
@Autowired
public SAMLSecurityConfig(SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl,
                          Environment environment, ApplicationEventPublisher applicationEventPublisher, AuthenticationConfiguration authenticationConfiguration) {
    this.samlUserDetailsServiceImpl = samlUserDetailsServiceImpl;
    this.environment = environment;
    this.applicationEventPublisher = applicationEventPublisher;
    this.authenticationConfiguration = authenticationConfiguration;
}
@Autowired
public  SAMLConfig samlConfig;

public SAMLConfig config() {
    samlConfig.setEntity();
    return samlConfig;
}
// Initialization of OpenSAML library
@Bean
public static SAMLBootstrap samlBootstrap() {
    return new CustomSAMLBootStrap();
}

@PostConstruct
public void init() {
    this.backgroundTaskTimer = new Timer(true);
    this.multiThreadedHttpConnectionManager = new MultiThreadedHttpConnectionManager();
}

@PreDestroy
public void destroy() {
    this.backgroundTaskTimer.purge();
    this.backgroundTaskTimer.cancel();
    this.multiThreadedHttpConnectionManager.shutdown();
}

// Initialization of the velocity engine
@Bean
public VelocityEngine velocityEngine() {
    VelocityEngine engine = new VelocityEngine();

    Properties props = new Properties();
    props.put("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
    props.put("runtime.log.logsystem.log4j.category", "velocity");
    props.put("runtime.log.logsystem.log4j.logger", "velocity");
    props.put("UTF-8", "UTF-8");
    props.put("resource.loader", "classpath");
    props.put("classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    engine.init(props);
    return engine;
}

// XML parser pool needed for OpenSAML parsing
@Bean(initMethod = "initialize")
public StaticBasicParserPool parserPool() {
    return new StaticBasicParserPool();
}

@Bean(name = "parserPoolHolder")
public ParserPoolHolder parserPoolHolder() {
    return new ParserPoolHolder();
}

// Bindings, encoders and decoders used for creating and parsing messages
@Bean
public HttpClient httpClient() {
    return new HttpClient(this.multiThreadedHttpConnectionManager);
}

// SAML Authentication Provider responsible for validating of received SAML
// messages
@Bean
public SAMLAuthenticationProvider samlAuthenticationProvider() {
    SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
    samlAuthenticationProvider.setUserDetails(samlUserDetailsServiceImpl);
    samlAuthenticationProvider.setForcePrincipalAsString(false);
    return samlAuthenticationProvider;
}

// Load Balancer Context Provider
@Bean
public SAMLContextProviderLB contextProvider() {
    SAMLContextProviderLB samlContextProviderLB = new SAMLContextProviderLB();
    samlContextProviderLB.setServerName(config().getSp().getServerName());
    samlContextProviderLB.setIncludeServerPortInRequestURL(false);
    samlContextProviderLB.setServerPort(config().getLb().getServerPort());
    samlContextProviderLB.setScheme(config().getLb().getScheme());
    samlContextProviderLB.setContextPath("/cms-service/webapi");
    return samlContextProviderLB;
}

// Logger for SAML messages and events
@Bean
public SAMLDefaultLogger samlLogger() {
    return new SAMLDefaultLogger();
}

// SAML 2.0 WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumer webSSOprofileConsumer() {
    return new WebSSOProfileConsumerImpl();
}

// SAML 2.0 WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumer hokWebSSOprofileConsumer() {
    WebSSOProfileConsumerImpl webSSOProfileConsumer = new WebSSOProfileConsumerImpl();
    webSSOProfileConsumer.setResponseSkew(180);
    webSSOProfileConsumer.setMaxAuthenticationAge(180);
    return webSSOProfileConsumer;
}

// SAML 2.0 Holder-of-Key WebSSO Assertion Consumer
@Bean
public WebSSOProfileConsumerHoKImpl hokWebSSOAssertionConsumer() {
    return new WebSSOProfileConsumerHoKImpl();
}

// SAML 2.0 Web SSO profile
@Bean
public WebSSOProfile webSSOprofile() {
    return new WebSSOProfileImpl();
}

// SAML 2.0 Holder-of-Key Web SSO profile
@Bean
public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() {
    return new WebSSOProfileConsumerHoKImpl();
}

// SAML 2.0 ECP profile
@Bean
public WebSSOProfileECPImpl ecpProfile() {
    return new WebSSOProfileECPImpl();
}

@Bean
public SingleLogoutProfile logoutProfile() {
    return new SingleLogoutProfileImpl();
}

/*
 * Central storage of cryptographic keys
 *
 * If your project does not require any keys you can replace the code below with:
 *    return new EmptyKeyManager();
 */
@Bean
public KeyManager keyManager() {
    KeyStore keyStore = null;
    try (FileInputStream fileInputStream = new FileInputStream(config().getKeyStore().getResource().getFile())) {
        keyStore = KeyStore.getInstance("JKS");
        keyStore.load(fileInputStream, config().getKeyStore().getPass().toCharArray());
    } catch (IOException | CertificateException | NoSuchAlgorithmException | KeyStoreException e) {
        LOGGER.debug("Error reading keystore file", e);
    }

    Map<String, String> passwords = new HashMap<>();
    passwords.put(config().getKeyStore().getAlias(), config().getKeyStore().getPass());

    assert keyStore != null;
    return new JKSKeyManager(keyStore, passwords, config().getKeyStore().getAlias());
}


@Bean
public WebSSOProfileOptions defaultWebSSOProfileOptions() {
    WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions();
    webSSOProfileOptions.setIncludeScoping(false);
    return webSSOProfileOptions;
}

// Entry point to initialize authentication, default values taken from
// properties file
@Bean
public SAMLEntryPoint samlEntryPoint() {
    SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint();
    samlEntryPoint.setWebSSOprofile(webSSOprofile());
    samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions());
    httpClient().getState().clear();
    return samlEntryPoint;
}

// Setup advanced info about metadata
@Bean
public ExtendedMetadata extendedMetadata() {
    ExtendedMetadata extendedMetadata = new ExtendedMetadata();
    extendedMetadata.setIdpDiscoveryEnabled(true);
    extendedMetadata.setSignMetadata(false);
    extendedMetadata.setEcpEnabled(true);
    extendedMetadata.setSslHostnameVerification(ALLOW_ALL.toString());
    return extendedMetadata;
}

// Filter automatically generates default SP metadata
@Bean
public MetadataGenerator metadataGenerator() {
    MetadataGenerator metadataGenerator = new MetadataGenerator();
    metadataGenerator.setEntityBaseURL(config().getSp().getEntityBaseURL());
    metadataGenerator.setEntityId(config().getSp().getEntityId());
    metadataGenerator.setExtendedMetadata(extendedMetadata());
    metadataGenerator.setIncludeDiscoveryExtension(true);
    metadataGenerator.setKeyManager(keyManager());
    return metadataGenerator;
}

// The filter is waiting for connections on URL suffixed with filterSuffix
// and presents SP metadata there
@Bean
public MetadataDisplayFilter metadataDisplayFilter() {
    return new MetadataDisplayFilter();
}

// Handler deciding where to redirect user after successful login
@Bean
public CustomAuthenticationSuccessHandler successRedirectHandler() {
    CustomAuthenticationSuccessHandler successRedirectHandler =
            new CustomAuthenticationSuccessHandler();
    successRedirectHandler.setDefaultTargetUrl(config().getSp().getEntityBaseURL());
    return successRedirectHandler;
}

// Handler deciding where to redirect user after failed login
@Bean
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
    SimpleUrlAuthenticationFailureHandler failureHandler =
            new CustomAuthenticationFailureHandler();
    failureHandler.setUseForward(false);
    failureHandler.setDefaultFailureUrl(config().getSp().getEntityBaseURL());
    return failureHandler;
}

@Bean
public SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter() throws Exception {
    SAMLWebSSOHoKProcessingFilter samlWebSSOHoKProcessingFilter = new SAMLWebSSOHoKProcessingFilter();
    samlWebSSOHoKProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
    samlWebSSOHoKProcessingFilter.setAuthenticationManager(authenticationManager());
    samlWebSSOHoKProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
    return samlWebSSOHoKProcessingFilter;
}

// Processing filter for WebSSO profile messages
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
    SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
    samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
    samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
    samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
    httpClient().getState().clear();
    return samlWebSSOProcessingFilter;
}

@Bean
public MetadataGeneratorFilter metadataGeneratorFilter() {
    return new MetadataGeneratorFilter(metadataGenerator());
}

// Handler for successful logout
@Bean
public SimpleUrlLogoutSuccessHandler successLogoutHandler() {
    SimpleUrlLogoutSuccessHandler successLogoutHandler = new CustomSimpleUrlLogoutSuccessHandler();
    successLogoutHandler.setDefaultTargetUrl(config().getSp().getEntityBaseURL());
    return successLogoutHandler;
}

// Logout handler terminating local session
@Bean
public SecurityContextLogoutHandler logoutHandler() {
    SecurityContextLogoutHandler logoutHandler =
            new SecurityContextLogoutHandler();
    logoutHandler.setInvalidateHttpSession(true);
    logoutHandler.setClearAuthentication(true);
    return logoutHandler;
}

// Filter processing incoming logout messages
// First argument determines URL user will be redirected to after successful
// global logout
@Bean
public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() {
    return new SAMLLogoutProcessingFilter(successLogoutHandler(),
            logoutHandler());
}

// Overrides default logout processing filter with the one processing SAML
// messages
@Bean
public SAMLLogoutFilter samlLogoutFilter() {
    return new SAMLLogoutFilter(successLogoutHandler(),
            new LogoutHandler[]{logoutHandler()},
            new LogoutHandler[]{logoutHandler()});
}

// Bindings
private ArtifactResolutionProfile artifactResolutionProfile() {
    final ArtifactResolutionProfileImpl artifactResolutionProfile =
            new ArtifactResolutionProfileImpl(httpClient());
    artifactResolutionProfile.setProcessor(new SAMLProcessorImpl(soapBinding()));
    return artifactResolutionProfile;
}

@Bean
public HTTPArtifactBinding artifactBinding(ParserPool parserPool, VelocityEngine velocityEngine) {
    return new HTTPArtifactBinding(parserPool, velocityEngine, artifactResolutionProfile());
}

@Bean
public HTTPSOAP11Binding soapBinding() {
    return new HTTPSOAP11Binding(parserPool());
}

@Bean
public HTTPPostBinding httpPostBinding() {
    return new HTTPPostBinding(parserPool(), velocityEngine());
}

@Bean
public HTTPRedirectDeflateBinding httpRedirectDeflateBinding() {
    return new HTTPRedirectDeflateBinding(parserPool());
}

@Bean
public HTTPSOAP11Binding httpSOAP11Binding() {
    return new HTTPSOAP11Binding(parserPool());
}

@Bean
public HTTPPAOS11Binding httpPAOS11Binding() {
    return new HTTPPAOS11Binding(parserPool());
}

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
    return new HttpSessionEventPublisher();
}

// Processor
@Bean
public SAMLProcessorImpl processor() {
    Collection<SAMLBinding> bindings = new ArrayList<>();
    bindings.add(httpRedirectDeflateBinding());
    bindings.add(httpPostBinding());
    bindings.add(artifactBinding(parserPool(), velocityEngine()));
    bindings.add(httpSOAP11Binding());
    bindings.add(httpPAOS11Binding());
    return new SAMLProcessorImpl(bindings);
}

/**
 * Define the security filter chain in order to support SSO Auth by using SAML 2.0
 *
 * @return Filter chain proxy
 */
@Bean
public FilterChainProxy samlFilter() throws Exception {
    List<SecurityFilterChain> chains = new ArrayList<>();
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
            samlEntryPoint()));
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/logout/**"),
            samlLogoutFilter()));
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"),
            metadataDisplayFilter()));
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"),
            samlWebSSOProcessingFilter()));
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSOHoK/**"),
            samlWebSSOHoKProcessingFilter()));
    chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"),
            samlLogoutProcessingFilter()));
    return new FilterChainProxy(chains);
}

/**
 * Returns the authentication manager currently used by Spring.
 * It represents a bean definition with the aim allow wiring from
 * other classes performing the Inversion of Control (IoC).
 *
 */
@Bean

public AuthenticationManager authenticationManagerBean(AuthenticationConfiguration authConfiguration) throws Exception {
    return authConfiguration.getAuthenticationManager();
}
@Bean
public AuthenticationManager authenticationManager() throws Exception {
    return authenticationConfiguration.getAuthenticationManager();
}

/**
 * Defines the web based security configuration.
 *
 * @param http It allows configuring web based security for specific http requests.
 *
 */
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.httpBasic(httpBasic-> httpBasic.authenticationEntryPoint(samlEntryPoint()));
    /*http
            .httpBasic()
            .authenticationEntryPoint(samlEntryPoint());*/
    /*http
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .ignoringAntMatchers("/saml/**");*/
    http.csrf(csrf->csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .ignoringRequestMatchers("/saml/**"));

    http
            .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
            .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
    /*http
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/saml/logout"))
            .deleteCookies("JSESSIONID")
            .logoutSuccessUrl(config().getSp().getEntityBaseURL() + LOGIN);*/
    http.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.logoutRequestMatcher(new AntPathRequestMatcher("/saml/logout"))
            .deleteCookies("JSESSIONID")
            .logoutSuccessUrl(config().getSp().getEntityBaseURL() + LOGIN));
    /*http
            .headers()
            .frameOptions()
            .disable();*/
    http.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
    /*http
            .sessionManagement()
            .sessionAuthenticationErrorUrl(config().getSp().getEntityBaseURL() + LOGIN)
            .invalidSessionUrl(config().getSp().getEntityBaseURL() + LOGIN);*/

    http.sessionManagement(sessionManagement -> sessionManagement.sessionAuthenticationErrorUrl(config().getSp().getEntityBaseURL() + LOGIN)
            .invalidSessionUrl(config().getSp().getEntityBaseURL() + LOGIN));
    /*http
            .sessionManagement()
            .maximumSessions(1)
            .expiredUrl(config().getSp().getEntityBaseURL() + LOGIN);*/
    http.sessionManagement(sessionManagement -> sessionManagement.maximumSessions(1)
            .expiredUrl(config().getSp().getEntityBaseURL() + LOGIN));
    /*http
            .sessionManagement()
            .sessionFixation()
            .newSession();*/
    http.sessionManagement(sessionManagement ->
            sessionManagement.sessionFixation().newSession());

    /*http
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER);*/
    http.sessionManagement(sessionManagement ->sessionManagement.sessionCreationPolicy(SessionCreationPolicy.NEVER));

            permitEndpoints(http);
    http.authenticationProvider(samlAuthenticationProvider());
    return http.build();
}

/**
 * Sets a custom authentication provider.
 *
 * @param auth SecurityBuilder used to create an AuthenticationManager.
 */
/*@Override
protected void configure(AuthenticationManagerBuilder auth) {
    auth.authenticationProvider(samlAuthenticationProvider());
}*/


private void permitEndpoints(HttpSecurity http) throws Exception {
    if (isSamlDisabled()) {
        http
                .authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests.requestMatchers("/**").permitAll()
                        .anyRequest().authenticated());
               // .requestMatchers("/**").permitAll()
                //.anyRequest().authenticated();
    } else {
        http
                .authorizeHttpRequests(authorizeHttpRequests ->
                        authorizeHttpRequests.requestMatchers("/saml/**").permitAll()
                                .requestMatchers("/error").permitAll().anyRequest().permitAll());
        /*
                .requestMatchers("/saml/**").permitAll()
                .requestMatchers("/error").permitAll()
                .anyRequest().permitAll();*/
    }
}

private boolean isSamlDisabled() {
    return Arrays.stream(environment.getActiveProfiles()).anyMatch(
            env -> (env.equalsIgnoreCase("samlDisabled")));
}

public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        logger.debug("in onAuthenticationSuccess");
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("XSRF-TOKEN")) {
                    cookie.setValue("");
                    cookie.setMaxAge(0);
                    cookie.setPath("/");
                    response.addCookie(cookie);
                }
            }
        }
        if(config().getSp().getEntityBaseURL().equalsIgnoreCase(this.getDefaultTargetUrl())) {
            URLBuilder builder = new URLBuilder(request.getRequestURL().toString());
            builder.setPath("/");
            builder.setFragment("/login?SSO="+ UserPolicy.AUTH_TYPE_SAML);
            builder.setPort(CmsUtil.getWebServerPort());
            this.setDefaultTargetUrl(builder.buildURL());
        }
        request.changeSessionId();
        super.onAuthenticationSuccess(request, response, authentication);
    }
}

public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    protected String defaultFailureUrl = null;

    public String getDefaultFailureUrl() {
        return defaultFailureUrl;
    }
    @Override
    public void setDefaultFailureUrl(String defaultFailureUrl) {
        super.setDefaultFailureUrl(defaultFailureUrl);
        this.defaultFailureUrl = defaultFailureUrl;
    }
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        logger.debug("in onAuthenticationFailure");
        if(config().getSp().getEntityBaseURL().equalsIgnoreCase(this.getDefaultFailureUrl())) {
            URLBuilder builder = new URLBuilder(request.getRequestURL().toString());
            builder.setPath("/");
            builder.setFragment("/login?SSO="+ UserPolicy.AUTH_TYPE_SAML);
            builder.setPort(CmsUtil.getWebServerPort());
            this.setDefaultFailureUrl(builder.buildURL());
        }
        super.onAuthenticationFailure(request, response, exception);
    }
}

public class CustomSimpleUrlLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                                Authentication authentication) throws IOException, ServletException {
        if(config().getSp().getEntityBaseURL().equalsIgnoreCase(this.getDefaultTargetUrl())) {
            URLBuilder builder = new URLBuilder(request.getRequestURL().toString());
            builder.setPath("/");
            builder.setFragment("/login");
            builder.setPort(CmsUtil.getWebServerPort());
            this.setDefaultTargetUrl(builder.buildURL());
        }
        super.onLogoutSuccess(request, response, authentication);
    }
}


@Bean
@Qualifier("idp-keycloak")
public ExtendedMetadataDelegate keycloakExtendedMetadataProvider(Environment env)
        throws MetadataProviderException {
    String idpKeycloakMetadataURL = env.getRequiredProperty("keycloak.auth-server-url") + "/protocol/saml/descriptor";
    HTTPMetadataProvider httpMetadataProvider = new HTTPMetadataProvider(
            this.backgroundTaskTimer, httpClient(), idpKeycloakMetadataURL);
    httpMetadataProvider.setParserPool(parserPool());
    ExtendedMetadataDelegate extendedMetadataDelegate =
            new ExtendedMetadataDelegate(httpMetadataProvider, extendedMetadata());
    extendedMetadataDelegate.setMetadataTrustCheck(true);
    extendedMetadataDelegate.setMetadataRequireSignature(false);
    backgroundTaskTimer.purge();
    return extendedMetadataDelegate;
}
@Bean
@Qualifier("metadata")
public CachingMetadataManager metadata(List<MetadataProvider> providers) throws MetadataProviderException {
    providers.remove(0);
    return new CachingMetadataManager(providers);
}
}

please advise.

1

There are 1 answers

9
Andrei Lisa On

Have you tried to declare an authenticationManager Bean in security configuration class?

Something like this:

  @Autowired
  private  AuthenticationConfiguration authenticationConfiguration; // or constructor injection depends on what you are using

      @Bean
      public AuthenticationManager authenticationManager() throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
      }

UPDATE: If you cannot do it with an method param, just use the above provided code.