diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index d5ad81e6..73213a77 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -8,7 +8,14 @@ import java.security.PrivateKey; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; + import org.bouncycastle.util.io.pem.PemReader; +import org.opensaml.saml.common.xml.SAMLConstants; +import org.opensaml.saml.saml2.core.AuthnContextClassRef; +import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration; +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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +38,10 @@ import org.springframework.security.saml2.provider.service.registration.InMemory import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; +import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; +import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver; +import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver; +import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; @@ -51,6 +62,9 @@ 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) @@ -68,6 +82,17 @@ public class SecurityConfig { public SecurityConfig(TokenProvider tokenProvider) { this.tokenProvider = tokenProvider; } +// +// @Bean +// public Saml2AuthenticationRequestResolver authenticationRequestResolver() { +// return (Saml2AuthenticationRequestContext context) -> { +// Saml2AuthenticationRequest request = Saml2AuthenticationRequest.withAuthenticationRequestContext(context) +// .authenticationContextClassRef("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword") // Add context here +// .build(); +// return request; +// }; +// } + @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); @@ -225,12 +250,41 @@ public class SecurityConfig { .assertionConsumerServiceLocation(acsUrl) .assertingPartyDetails(details -> details.entityId("https://federatest.umbriadigitale.it/gw/metadata") .singleSignOnServiceLocation("https://federatest.umbriadigitale.it/gw/SSOProxy/SAML2") - .singleSignOnServiceBinding(Saml2MessageBinding.POST).wantAuthnRequestsSigned(true) + .singleSignOnServiceBinding(Saml2MessageBinding.POST).wantAuthnRequestsSigned(true).build() ) .build(); return new InMemoryRelyingPartyRegistrationRepository(registration); } + @Bean + public Saml2AuthenticationRequestResolver authenticationRequestResolver(RelyingPartyRegistrationRepository registrations) { + RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(registrations); + OpenSaml4AuthenticationRequestResolver authenticationRequestResolver = new OpenSaml4AuthenticationRequestResolver(registrationResolver); + + // Customize the AuthnRequest with the authentication context + authenticationRequestResolver.setAuthnRequestCustomizer((context) -> { + context.getAuthnRequest().setRequestedAuthnContext(buildRequestedAuthnContext()); + }); + + return authenticationRequestResolver; + } + + private RequestedAuthnContext buildRequestedAuthnContext() { + AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder(); + AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject( + SAMLConstants.SAML20_NS, AuthnContextClassRef.DEFAULT_ELEMENT_LOCAL_NAME, SAMLConstants.SAML20_PREFIX + ); + + // Set the SPID Level 2 authentication context + authnContextClassRef.setURI("urn:oasis:names:tc:SAML:2.0:ac:classes:SecureRemotePassword"); + + RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder(); + RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject(); + requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT); + requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef); + + return requestedAuthnContext; + } public PrivateKey readPrivateKey() throws Exception {