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:
- Actualiza las importaciones para utilizar las clases de OpenSAML 4.0.1.
- 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
- 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.
- Limpieza y Reconstrucción: Después de realizar estos cambios, limpia y reconstruye tu proyecto usando Maven:bashCopiar código
mvn clean install
- Verificación de Dependencias: Asegúrate de que las dependencias sean correctas y no haya conflictos utilizando el comando:bashCopiar código
mvn dependency:tree
- Probar la Aplicación: Ejecuta tu aplicación nuevamente para verificar que el problema se ha resuelto.
No encontre xmltooling 4.0.1
Devxperience propuesta.
Hemos visto tu negocio y creemos que tiene mucho potencial.
Publicaremos tu empresa en más de 60 periódicos digitales de alta autoridad, lo que mejorará tu reputación, y posicionará tu web en las primeras posiciones de Internet. Así, cuando los clientes busquen información sobre ti, verán que tu empresa es conocida y confiarán más en ella.
Además, queremos ofrecerte dos meses gratuitos para que pruebes el impacto sin compromiso.
¿Podrías facilitarme un número de teléfono para comentarte los detalles?
Quedo pendiente de tu respuesta.
PD: Si prefieres no recibir más información, responde con “No estoy interesado” y no volveremos a contactarte.
muScBka rEATAk dJkvkTG qqpwvrP hXoSt Kzc TkPJxVlH
Devxperience propuesta.
Hemos visto tu negocio y creemos que tiene mucho potencial.
Publicaremos tu empresa en más de 60 periódicos digitales de alta autoridad, lo que mejorará tu reputación, y posicionará tu web en las primeras posiciones de Internet. Así, cuando los clientes busquen información sobre ti, verán que tu empresa es conocida y confiarán más en ella.
Además, queremos ofrecerte dos meses gratuitos para que pruebes el impacto sin compromiso.
¿Podrías facilitarme un número de teléfono para comentarte los detalles?
Quedo pendiente de tu respuesta.
PD: Si prefieres no recibir más información, responde con “No estoy interesado” y no volveremos a contactarte.
Devxperience propuesta.
Hemos visto tu negocio y creemos que tiene mucho potencial.
Publicaremos tu empresa en más de 60 periódicos digitales de alta autoridad, lo que mejorará tu reputación, y posicionará tu web en las primeras posiciones de Internet. Así, cuando los clientes busquen información sobre ti, verán que tu empresa es conocida y confiarán más en ella.
Además, queremos ofrecerte dos meses gratuitos para que pruebes el impacto sin compromiso.
¿Podrías facilitarme un número de teléfono para comentarte los detalles?
Quedo pendiente de tu respuesta.
PD: Si prefieres no recibir más información, responde con “No estoy interesado” y no volveremos a contactarte.
Devxperience propuesta.
Hemos visto tu negocio y creemos que tiene mucho potencial.
Publicaremos tu empresa en más de 60 periódicos digitales de alta autoridad, lo que mejorará tu reputación, y posicionará tu web en las primeras posiciones de Internet. Así, cuando los clientes busquen información sobre ti, verán que tu empresa es conocida y confiarán más en ella.
Además, queremos ofrecerte dos meses gratuitos para que pruebes el impacto sin compromiso.
¿Podrías facilitarme un número de teléfono para comentarte los detalles?
Quedo pendiente de tu respuesta.
PD: Si prefieres no recibir más información, responde con “No estoy interesado” y no volveremos a contactarte.