diff --git a/pom.xml b/pom.xml
index e8fb4bca..e10bc152 100644
--- a/pom.xml
+++ b/pom.xml
@@ -172,6 +172,13 @@
spring-cloud-starter-openfeign
4.1.3
+
+
+ org.apache.santuario
+ xmlsec
+ 2.3.0
+
+
diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java
index ac2ade2c..c645cee1 100644
--- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java
+++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java
@@ -1,4 +1,6 @@
package net.gepafin.tendermanagement.config;
+
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -8,9 +10,12 @@ import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
+import java.time.Instant;
import java.util.UUID;
import org.bouncycastle.util.io.pem.PemReader;
+import org.opensaml.core.config.InitializationService;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.saml.common.SAMLVersion;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.saml2.core.AuthnContextClassRef;
@@ -19,6 +24,11 @@ import org.opensaml.saml.saml2.core.AuthnRequest;
import org.opensaml.saml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml.saml2.core.impl.AuthnContextClassRefBuilder;
import org.opensaml.saml.saml2.core.impl.RequestedAuthnContextBuilder;
+import org.opensaml.security.x509.BasicX509Credential;
+import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
+import org.opensaml.xmlsec.signature.Signature;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
+import org.opensaml.xmlsec.signature.support.Signer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -55,19 +65,19 @@ import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
-
+import org.apache.xml.security.Init;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
+import jakarta.annotation.PostConstruct;
import net.gepafin.tendermanagement.config.jwt.JWTFilter;
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
import net.gepafin.tendermanagement.entities.SamlResponseLogEntity;
import net.gepafin.tendermanagement.repositories.SamlResponseLogRepository;
//import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext;
//import org.springframework.security.saml2.core.Saml2AuthenticationRequest;
-
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
@@ -85,6 +95,21 @@ public class SecurityConfig {
public SecurityConfig(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
+
+
+
+ @PostConstruct
+ public void initXmlSecurity() throws Exception {
+ // Initialize Apache XML Security (Santuario)
+ Init.init();
+ }
+
+
+ @PostConstruct
+ public void initOpenSAML() throws Exception {
+ InitializationService.initialize();
+ }
+
//
// @Bean
// public Saml2AuthenticationRequestResolver authenticationRequestResolver() {
@@ -259,6 +284,38 @@ public class SecurityConfig {
return new InMemoryRelyingPartyRegistrationRepository(registration);
}
+ public AuthnRequest createSignedAuthnRequest(PrivateKey privateKey, X509Certificate certificate) throws Exception {
+ AuthnRequest authnRequest = (AuthnRequest) XMLObjectProviderRegistrySupport.getBuilderFactory()
+ .getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME)
+ .buildObject(AuthnRequest.DEFAULT_ELEMENT_NAME);
+
+ authnRequest.setID("_" + UUID.randomUUID().toString());
+ authnRequest.setVersion(SAMLVersion.VERSION_20);
+ // authnRequest.setIssueInstant(new DateTime());
+ authnRequest.setIssueInstant(Instant.now());
+
+
+ // Sign the AuthnRequest
+ // BasicCredential signingCredential = new BasicCredential(certificate, privateKey);
+ BasicX509Credential signingCredential = new BasicX509Credential(certificate, privateKey);
+
+ Signature signature = (Signature) XMLObjectProviderRegistrySupport.getBuilderFactory()
+ .getBuilder(Signature.DEFAULT_ELEMENT_NAME)
+ .buildObject(Signature.DEFAULT_ELEMENT_NAME);
+
+ signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+ signature.setSigningCredential(signingCredential);
+ signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1); // Set RSA-SHA1
+
+ authnRequest.setSignature(signature);
+ DefaultSecurityConfigurationBootstrap.buildDefaultSignatureSigningConfiguration();
+
+ // Marshall and sign the object
+ XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(authnRequest).marshall(authnRequest);
+ Signer.signObject(signature);
+
+ return authnRequest;
+ }
@Bean
public Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationRepository registrations) {