devxperience.tech

Integración con okta en una aplicación de spring boot 3 maven

El problema que estás encontrando con la integración de SAML en Spring Boot 3.1.11 parece estar relacionado con las versiones de las bibliotecas de OpenSAML que estás utilizando. Dado que XSAnyBuilder no puede ser casteado a XMLObjectBuilder, es probable que tengas versiones incompatibles de las bibliotecas de OpenSAML.

Revisión y Ajuste del pom.xml

Primero, asegúrate de que todas las dependencias de OpenSAML sean consistentes y compatibles entre sí. Aquí tienes un ejemplo ajustado de tu pom.xml con las versiones correctas de las bibliotecas de OpenSAML:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.1.11</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<repositories>
		<repository>
			<id>Shibboleth</id>
			<name>Shibboleth</name>
			<url>https://build.shibboleth.net/nexus/content/repositories/releases/</url>
		</repository>
		<repository>
			<id>central</id>
			<url>https://repo.maven.apache.org/maven2</url>
		</repository>
		<repository>
			<id>sonatype</id>
			<url>https://oss.sonatype.org/content/repositories/releases/</url>
		</repository>
	</repositories>

	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.opensaml</groupId>
				<artifactId>opensaml-bom</artifactId>
				<version>4.0.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-tomcat</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>2.17.2</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.security.extensions</groupId>
			<artifactId>spring-security-saml2-core</artifactId>
			<version>1.0.10.RELEASE</version>
			<exclusions>
				<exclusion>
					<groupId>org.owasp.esapi</groupId>
					<artifactId>esapi</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.opensaml</groupId>
					<artifactId>opensaml</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.opensaml</groupId>
					<artifactId>xmltooling</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.opensaml</groupId>
					<artifactId>openws</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-saml2-service-provider</artifactId>
			<version>5.5.3</version>
		</dependency>

		<dependency>
			<groupId>org.opensaml</groupId>
			<artifactId>opensaml-saml-impl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.opensaml</groupId>
			<artifactId>opensaml-saml-api</artifactId>
		</dependency>
		<dependency>
			<groupId>org.opensaml</groupId>
			<artifactId>opensaml-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.opensaml</groupId>
			<artifactId>xmltooling</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>6.0.0</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>

	<build>
		<finalName>demo</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Ajustes en la Clase SamlSecurityConfig

En la clase SamlSecurityConfig, necesitas asegurarte de que estás utilizando las clases correctas y compatibles de OpenSAML. Aquí hay un ejemplo de cómo ajustar la clase:

  1. Actualiza las importaciones para utilizar las clases de OpenSAML 4.0.1.
  2. Corrige cualquier referencia a clases obsoletas o incompatibles.

Aquí está la versión ajustada de la clase SamlSecurityConfig:


package com.example.demo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;

import javax.sql.DataSource;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.velocity.app.VelocityEngine;
import org.opensaml.saml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.saml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.saml.saml2.metadata.provider.ResourceBackedMetadataProvider;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.parse.BasicParserPool;
import org.opensaml.core.xml.parse.StaticBasicParserPool;
import org.opensaml.core.xml.util.XMLObjectSupport;
import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver;
import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.saml.SAMLAuthenticationProvider;
import org.springframework.security.saml.SAMLBootstrap;
import org.springframework.security.saml.SAMLEntryPoint;
import org.springframework.security.saml.SAMLLogoutFilter;
import org.springframework.security.saml.SAMLLogoutProcessingFilter;
import org.springframework.security.saml.SAMLProcessingFilter;
import org.springframework.security.saml.SAMLWebSSOHoKProcessingFilter;
import org.springframework.security.saml.context.SAMLContextProviderImpl;
import org.springframework.security.saml.key.JKSKeyManager;
import org.springframework.security.saml.key.KeyManager;
import org.springframework.security.saml.log.SAMLDefaultLogger;
//import org.springframework.security.saml.log.SAMLDefaultLogger;
import org.springframework.security.saml.metadata.CachingMetadataManager;
import org.springframework.security.saml.metadata.ExtendedMetadata;
import org.springframework.security.saml.metadata.ExtendedMetadataDelegate;
import org.springframework.security.saml.metadata.MetadataDisplayFilter;
import org.springframework.security.saml.metadata.MetadataGenerator;
import org.springframework.security.saml.metadata.MetadataGeneratorFilter;
import org.springframework.security.saml.parser.ParserPoolHolder;
import org.springframework.security.saml.processor.HTTPArtifactBinding;
import org.springframework.security.saml.processor.HTTPPAOS11Binding;
import org.springframework.security.saml.processor.HTTPPostBinding;
import org.springframework.security.saml.processor.HTTPRedirectDeflateBinding;
import org.springframework.security.saml.processor.HTTPSOAP11Binding;
import org.springframework.security.saml.processor.SAMLBinding;
import org.springframework.security.saml.processor.SAMLProcessorImpl;
import org.springframework.security.saml.storage.EmptyStorageFactory;
import org.springframework.security.saml.userdetails.SAMLUserDetailsService;
import org.springframework.security.saml.util.VelocityFactory;
import org.springframework.security.saml.websso.ArtifactResolutionProfile;
import org.springframework.security.saml.websso.ArtifactResolutionProfileImpl;
import org.springframework.security.saml.websso.SingleLogoutProfile;
import org.springframework.security.saml.websso.SingleLogoutProfileImpl;
import org.springframework.security.saml.websso.WebSSOProfile;
import org.springframework.security.saml.websso.WebSSOProfileConsumer;
import org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl;
import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl;
import org.springframework.security.saml.websso.WebSSOProfileECPImpl;
import org.springframework.security.saml.websso.WebSSOProfileImpl;
import org.springframework.security.saml.websso.WebSSOProfileOptions;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.example.saml.SamlUserDetailsServiceImpl;

import net.shibboleth.utilities.java.support.xml.ParserPool;

@Configuration
public class SamlSecurityConfig {

	@Value("${JKS_APP}")
	private String _jksApp;

	@Value("${JKS_PASS}")
	private String pwcert;

	@Value("${URLLOGOUT}")
	private String urlLogout;

	@Value("${VARIABLE_WS}")
	private String rutaConfiguracion;

	@Value("${PATHJKS}")
	private String pathJKS;

	@Value("${PATHIDP}")
	private String pathIdp;

	@Value("${SAML.IDP}")
	private String defaultIdp;

	@Value("${SAML.SP}")
	private String samlAudience;

	@Value("${URL_APP_WS}")
	private String entityBaseURL;

	@Value("${APP_NAME}")
	private String _appName;

	private JdbcTemplate jdbcToolsnetUsr;

	@Autowired
	public void setDatasource(@Qualifier("dsUsuarios") DataSource toolsnetUserDS) {
		this.jdbcToolsnetUsr = new JdbcTemplate(toolsnetUserDS);
	}

	@Bean
	public SAMLUserDetailsService samlUserDetailsService() {
		return new SamlUserDetailsServiceImpl(this._appName, jdbcToolsnetUsr);
	}

	@Bean
	public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}

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

	@Bean
	public SAMLEntryPoint samlEntryPoint() {
		WebSSOProfileOptions options = new WebSSOProfileOptions();
		options.setIncludeScoping(false);
		SAMLEntryPoint entryPoint = new SAMLEntryPoint();
		entryPoint.setDefaultProfileOptions(options);
		entryPoint.setFilterProcessesUrl("/saml/login");
		return entryPoint;
	}

	@Bean
	public MetadataDisplayFilter metadataDisplayFilter() {
		return new MetadataDisplayFilter();
	}

	@Bean
	public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
		SimpleUrlAuthenticationFailureHandler failureRedirectHandler = new SimpleUrlAuthenticationFailureHandler();
		failureRedirectHandler.setUseForward(true);
		failureRedirectHandler.setDefaultFailureUrl("/error");
		return failureRedirectHandler;
	}

	@Bean
	public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() {
		SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler = new SavedRequestAwareAuthenticationSuccessHandler();
		successRedirectHandler.setAlwaysUseDefaultTargetUrl(true);
		successRedirectHandler.setDefaultTargetUrl("/auth/access");
		return successRedirectHandler;
	}

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

	@Bean
	public SimpleUrlLogoutSuccessHandler successLogoutHandler() {
		SimpleUrlLogoutSuccessHandler handler = new SimpleUrlLogoutSuccessHandler();
		handler.setAlwaysUseDefaultTargetUrl(true);
		handler.setDefaultTargetUrl(urlLogout);
		return handler;
	}

	@Bean
	public SecurityContextLogoutHandler logoutHandler() {
		SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
		logoutHandler.setInvalidateHttpSession(true);
		logoutHandler.setClearAuthentication(true);
		return logoutHandler;
	}

	@Bean
	public SAMLLogoutFilter samlLogoutFilter() {
		return new SAMLLogoutFilter(successLogoutHandler(), new LogoutHandler[] { logoutHandler() }, new LogoutHandler[] { logoutHandler() });
	}

	@Bean
	public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() {
		return new SAMLLogoutProcessingFilter(successLogoutHandler(), logoutHandler());
	}

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

	@Bean
	public KeyManager keyManager() {
		DefaultResourceLoader loader = new DefaultResourceLoader();
		Resource resource = loader.getResource("file:" + rutaConfiguracion + pathJKS);
		System.out.println("-----------");
		System.out.println("Se carga JKS " + resource);
		System.out.println("-----------");
		String storePass = pwcert;
		Map<String, String> mapKeys = new HashMap<>();
		mapKeys.put(this._jksApp, storePass);
		return new JKSKeyManager(resource, storePass, mapKeys, this._jksApp);
	}

	@Bean
	@Qualifier("okta")
	public ExtendedMetadataDelegate oktaExtendedMetadataProvider() throws MetadataProviderException {
		Timer backgroundTaskTimer = new Timer(true);
		FilesystemMetadataResolver resolver = new FilesystemMetadataResolver(new java.io.File(rutaConfiguracion + pathIdp));
		resolver.setParserPool(parserPool());
		resolver.setMinRefreshDelay(900000);
		resolver.setMaxRefreshDelay(1200000);
		ExtendedMetadataDelegate extendedMetadataDelegate = new ExtendedMetadataDelegate(resolver, extendedMetadata());
		extendedMetadataDelegate.setMetadataTrustCheck(false);
		return extendedMetadataDelegate;
	}

	@Bean
	public ExtendedMetadata extendedMetadata() {
		ExtendedMetadata extendedMetadata = new ExtendedMetadata();
		extendedMetadata.setSigningKey(this._jksApp);
		extendedMetadata.setEncryptionKey(this._jksApp);
		extendedMetadata.setRequireLogoutRequestSigned(true);
		extendedMetadata.setRequireLogoutResponseSigned(false);
		extendedMetadata.setIdpDiscoveryEnabled(false);
		return extendedMetadata;
	}

	@Bean
	public MetadataGenerator metadataGenerator() {
		System.out.println("-----------");
		System.out.println("Ingreso a Metadata");
		System.out.println("-----------");
		MetadataGenerator metadataGenerator = new MetadataGenerator();
		metadataGenerator.setEntityId(samlAudience);
		metadataGenerator.setExtendedMetadata(extendedMetadata());
		metadataGenerator.setIncludeDiscoveryExtension(false);
		metadataGenerator.setKeyManager(keyManager());
		metadataGenerator.setEntityBaseURL(entityBaseURL);
		return metadataGenerator;
	}

	@Bean
	public FilterChainProxy samlFilter() throws Exception {
		List<SecurityFilterChain> chains = new ArrayList<>();
		chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"), metadataDisplayFilter()));
		chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"), samlEntryPoint()));
		chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"), samlEntryPoint()));
		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/logout/**"), samlLogoutFilter()));
		chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"), samlLogoutProcessingFilter()));
		return new FilterChainProxy(chains);
	}

	@Bean
	public VelocityEngine velocityEngine() {
		return VelocityFactory.getEngine();
	}

	@Bean(initMethod = "initialize")
	public StaticBasicParserPool parserPool() {
		return new StaticBasicParserPool();
	}

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

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

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

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

	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 HTTPPAOS11Binding paosBinding() {
		return new HTTPPAOS11Binding(parserPool());
	}

	@Bean
	public SAMLProcessorImpl processor() {
		Collection<SAMLBinding> bindings = new ArrayList<>();
		bindings.add(httpRedirectDeflateBinding());
		bindings.add(httpPostBinding());
		return new SAMLProcessorImpl(bindings);
	}

	@Bean
	public HttpClient httpClient() {
		return new HttpClient(multiThreadedHttpConnectionManager());
	}

	@Bean
	public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() {
		return new MultiThreadedHttpConnectionManager();
	}

	@Bean
	public static SAMLBootstrap sAMLBootstrap() {
		return new SAMLBootstrap();
	}

	@Bean
	public SAMLDefaultLogger samlLogger() {
		SAMLDefaultLogger samlLogger = new SAMLDefaultLogger();
		samlLogger.setLogErrors(true);
		samlLogger.setLogMessagesOnException(true);
		return samlLogger;
	}

	@Bean
	public EmptyStorageFactory emptyStorageFactory() {
		return new EmptyStorageFactory();
	}

	@Bean
	public SAMLContextProviderImpl contextProvider() {
		SAMLContextProviderImpl a = new SAMLContextProviderImpl();
		a.setStorageFactory(emptyStorageFactory());
		return new SAMLContextProviderImpl();
	}

	@Bean
	public WebSSOProfileConsumer webSSOprofileConsumer() {
		return new WebSSOProfileConsumerImpl();
	}

	@Bean
	public WebSSOProfile webSSOprofile() {
		return new WebSSOProfileImpl();
	}

	@Bean
	public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() {
		return new WebSSOProfileConsumerHoKImpl();
	}

	@Bean
	public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() {
		return new WebSSOProfileConsumerHoKImpl();
	}

	@Bean
	public WebSSOProfileECPImpl ecpProfile() {
		return new WebSSOProfileECPImpl();
	}

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

	@Bean
	@Qualifier("metadata")
	public CachingMetadataManager metadata() throws MetadataProviderException {
		List<MetadataProvider> providers = new ArrayList<>();
		providers.add(oktaExtendedMetadataProvider());
		CachingMetadataManager metadataManager = new CachingMetadataManager(providers);
		metadataManager.setDefaultIDP(defaultIdp);
		return new CachingMetadataManager(providers);
	}

	@Bean
	public SAMLAuthenticationProvider samlAuthenticationProvider() {
		SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
		samlAuthenticationProvider.setUserDetails(samlUserDetailsService());
		samlAuthenticationProvider.setForcePrincipalAsString(false);
		return samlAuthenticationProvider;
	}

	@Bean
	public AuthenticationManager authenticationManager() throws Exception {
		return new ProviderManager(samlAuthenticationProvider());
	}

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

	@Bean
	public SessionRegistry sessionRegistry() {
		return new SessionRegistryImpl();
	}

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

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.csrf(AbstractHttpConfigurer::disable);
		http.httpBasic(basic -> basic.authenticationEntryPoint(samlEntryPoint()));
		http.addFilterAfter(metadataGeneratorFilter(), ChannelProcessingFilter.class).addFilterAfter(samlFilter(),
				BasicAuthenticationFilter.class);
		http.authorizeHttpRequests(authz -> authz.requestMatchers("/**").permitAll().anyRequest().authenticated());
		return http.build();
	}
}

Notas Importantes

  1. Cambios en las Clases de OpenSAML: Asegúrate de que todas las clases e interfaces utilizadas en la configuración están correctamente importadas de las nuevas versiones de OpenSAML.
  2. Limpieza y Reconstrucción: Después de realizar estos cambios, limpia y reconstruye tu proyecto usando Maven:bashCopiar códigomvn clean install
  3. Verificación de Dependencias: Asegúrate de que las dependencias sean correctas y no haya conflictos utilizando el comando:bashCopiar códigomvn dependency:tree
  4. Probar la Aplicación: Ejecuta tu aplicación nuevamente para verificar que el problema se ha resuelto.

Como agrega un JDatePicker en netbeans

Para agregar un selector de fecha y hora en un proyecto Java Swing utilizando NetBeans, puedes seguir estos pasos:

Paso 1: Configurar el proyecto en NetBeans

  1. Abre NetBeans y crea un nuevo proyecto Java.
  2. Añade la biblioteca JDatePicker al proyecto:
    • Descarga JDatePicker desde JDatePicker GitHub.
    • En NetBeans, haz clic derecho en el proyecto y selecciona Propiedades.
    • Ve a Bibliotecas y haz clic en Agregar JAR/Carpeta.
    • Selecciona el archivo JAR de JDatePicker y haz clic en Abrir.

Paso 2: Crear la interfaz gráfica con NetBeans

  1. Crea un nuevo JFrame Form:
    • Haz clic derecho en el paquete de tu proyecto y selecciona Nuevo > JFrame Form.
  2. Agrega componentes al JFrame:
    • Usa el Palette en NetBeans para arrastrar y soltar componentes en tu formulario.
    • Agrega un JPanel para contener el selector de fecha y otro JPanel para el selector de hora.

Paso 3: Implementar el código para los selectores de fecha y hora

Edita el código del JFrame para agregar e inicializar los selectores de fecha y hora. A continuación se muestra un ejemplo completo que puedes adaptar a tu proyecto:

import org.jdatepicker.impl.JDatePanelImpl;
import org.jdatepicker.impl.JDatePickerImpl;
import org.jdatepicker.impl.UtilDateModel;

import javax.swing.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Properties;

public class DateTimePickerForm extends javax.swing.JFrame {

    public DateTimePickerForm() {
        initComponents();
        initDatePicker();
        initTimeSpinner();
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Date and Time Picker");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 200, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 200, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(50, 50, 50)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(50, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(50, 50, 50)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(50, Short.MAX_VALUE))
        );

        pack();
    }

    private void initDatePicker() {
        UtilDateModel model = new UtilDateModel();
        Properties p = new Properties();
        p.put("text.today", "Today");
        p.put("text.month", "Month");
        p.put("text.year", "Year");
        JDatePanelImpl datePanel = new JDatePanelImpl(model, p);
        JDatePickerImpl datePicker = new JDatePickerImpl(datePanel, new DateLabelFormatter());

        jPanel1.setLayout(new FlowLayout());
        jPanel1.add(datePicker);
    }

    private void initTimeSpinner() {
        SpinnerDateModel timeModel = new SpinnerDateModel();
        JSpinner timeSpinner = new JSpinner(timeModel);
        JSpinner.DateEditor timeEditor = new JSpinner.DateEditor(timeSpinner, "HH:mm:ss");
        timeSpinner.setEditor(timeEditor);

        jPanel2.setLayout(new FlowLayout());
        jPanel2.add(timeSpinner);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DateTimePickerForm().setVisible(true);
            }
        });
    }

    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;

    class DateLabelFormatter extends JFormattedTextField.AbstractFormatter {
        private String datePattern = "yyyy-MM-dd";
        private SimpleDateFormat dateFormatter = new SimpleDateFormat(datePattern);

        @Override
        public Object stringToValue(String text) throws ParseException {
            return dateFormatter.parseObject(text);
        }

        @Override
        public String valueToString(Object value) throws ParseException {
            if (value != null) {
                Calendar cal = (Calendar) value;
                return dateFormatter.format(cal.getTime());
            }
            return "";
        }
    }
}