diff --git a/build.gradle b/build.gradle index c1302656c4..e951f0c709 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,8 @@ buildscript { common_utils_version = System.getProperty("common_utils.version", '3.0.0.0-SNAPSHOT') kafka_version = '3.5.0' + open_saml_version = '4.0.1' + one_login_java_saml = '2.9.0' if (buildVersionQualifier) { opensearch_build += "-${buildVersionQualifier}" @@ -488,8 +490,6 @@ dependencies { implementation 'com.github.wnameless:json-flattener:0.5.0' implementation 'com.flipkart.zjsonpatch:zjsonpatch:0.4.4' implementation "org.apache.kafka:kafka-clients:${kafka_version}" - implementation 'com.onelogin:java-saml:2.5.0' - implementation 'com.onelogin:java-saml-core:2.5.0' runtimeOnly 'net.minidev:accessors-smart:2.4.7' @@ -508,23 +508,27 @@ dependencies { testImplementation 'org.apache.camel:camel-xmlsecurity:3.14.2' - implementation 'net.shibboleth.utilities:java-support:7.5.1' - implementation 'org.opensaml:opensaml-core:3.4.5' - implementation 'org.opensaml:opensaml-security-impl:3.4.5' - implementation 'org.opensaml:opensaml-security-api:3.4.5' - implementation 'org.opensaml:opensaml-xmlsec-api:3.4.5' - implementation 'org.opensaml:opensaml-xmlsec-impl:3.4.5' - implementation 'org.opensaml:opensaml-saml-api:3.4.5' - implementation ('org.opensaml:opensaml-saml-impl:3.4.5') { + // SAML + implementation "com.onelogin:java-saml:${one_login_java_saml}" + implementation "com.onelogin:java-saml-core:${one_login_java_saml}" + implementation 'net.shibboleth.utilities:java-support:7.5.2' + implementation "org.opensaml:opensaml-core:${open_saml_version}" + implementation "org.opensaml:opensaml-security-impl:${open_saml_version}" + implementation "org.opensaml:opensaml-security-api:${open_saml_version}" + implementation "org.opensaml:opensaml-xmlsec-api:${open_saml_version}" + implementation "org.opensaml:opensaml-xmlsec-impl:${open_saml_version}" + implementation "org.opensaml:opensaml-saml-api:${open_saml_version}" + implementation ("org.opensaml:opensaml-saml-impl:${open_saml_version}") { exclude(group: 'org.apache.velocity', module: 'velocity') } + testImplementation "org.opensaml:opensaml-messaging-impl:${open_saml_version}" + implementation "org.opensaml:opensaml-messaging-api:${open_saml_version}" + runtimeOnly "org.opensaml:opensaml-profile-api:${open_saml_version}" + runtimeOnly "org.opensaml:opensaml-soap-api:${open_saml_version}" + runtimeOnly "org.opensaml:opensaml-soap-impl:${open_saml_version}" + implementation "org.opensaml:opensaml-storage-api:${open_saml_version}" + implementation "com.nulab-inc:zxcvbn:1.7.0" - testImplementation 'org.opensaml:opensaml-messaging-impl:3.4.5' - implementation 'org.opensaml:opensaml-messaging-api:3.4.5' - runtimeOnly 'org.opensaml:opensaml-profile-api:3.4.5' - runtimeOnly 'org.opensaml:opensaml-soap-api:3.4.5' - runtimeOnly 'org.opensaml:opensaml-soap-impl:3.4.5' - implementation 'org.opensaml:opensaml-storage-api:3.4.5' implementation 'commons-lang:commons-lang:2.4' implementation 'commons-collections:commons-collections:3.2.2' implementation 'com.jayway.jsonpath:json-path:2.4.0' diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java b/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java index 881c9c3553..1b97242762 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java @@ -14,6 +14,7 @@ import java.security.AccessController; import java.security.PrivateKey; import java.security.PrivilegedAction; +import java.time.Instant; import java.util.AbstractMap; import java.util.Collection; import java.util.HashMap; @@ -28,7 +29,6 @@ import net.shibboleth.utilities.java.support.resolver.ResolverException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.joda.time.DateTime; import org.opensaml.core.criterion.EntityIdCriterion; import org.opensaml.saml.metadata.resolver.MetadataResolver; import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver; @@ -54,7 +54,7 @@ public class Saml2SettingsProvider { private final String idpEntityId; private final PrivateKey spSignaturePrivateKey; private Saml2Settings cachedSaml2Settings; - private DateTime metadataUpdateTime; + private Instant metadataUpdateTime; Saml2SettingsProvider(Settings opensearchSettings, MetadataResolver metadataResolver, PrivateKey spSignaturePrivateKey) { this.opensearchSettings = opensearchSettings; @@ -107,7 +107,7 @@ Saml2Settings get() throws SamlConfigException { } Saml2Settings getCached() throws SamlConfigException { - DateTime tempLastUpdate = null; + Instant tempLastUpdate = null; if (this.metadataResolver instanceof RefreshableMetadataResolver && this.isUpdateRequired()) { this.cachedSaml2Settings = null; diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/SamlHTTPMetadataResolver.java b/src/main/java/com/amazon/dlic/auth/http/saml/SamlHTTPMetadataResolver.java index 015e8df12d..2a380539e6 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/SamlHTTPMetadataResolver.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/SamlHTTPMetadataResolver.java @@ -15,6 +15,7 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.time.Duration; import net.shibboleth.utilities.java.support.resolver.ResolverException; import org.apache.http.client.HttpClient; @@ -31,8 +32,8 @@ public class SamlHTTPMetadataResolver extends HTTPMetadataResolver { SamlHTTPMetadataResolver(String idpMetadataUrl, Settings opensearchSettings, Path configPath) throws Exception { super(createHttpClient(opensearchSettings, configPath), idpMetadataUrl); - setMinRefreshDelay(opensearchSettings.getAsLong("idp.min_refresh_delay", 60L * 1000L)); - setMaxRefreshDelay(opensearchSettings.getAsLong("idp.max_refresh_delay", 14400000L)); + setMinRefreshDelay(Duration.ofMillis(opensearchSettings.getAsLong("idp.min_refresh_delay", 60L * 1000L))); + setMaxRefreshDelay(Duration.ofMillis(opensearchSettings.getAsLong("idp.max_refresh_delay", 14400000L))); setRefreshDelayFactor(opensearchSettings.getAsFloat("idp.refresh_delay_factor", 0.75f)); } diff --git a/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java b/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java index ef54e3e833..3db92757c1 100644 --- a/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java +++ b/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java @@ -32,6 +32,8 @@ import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; @@ -82,7 +84,6 @@ import org.apache.hc.core5.http.message.BasicHttpRequest; import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.net.URIBuilder; -import org.joda.time.DateTime; import org.opensaml.core.xml.XMLObject; import org.opensaml.core.xml.XMLObjectBuilderFactory; import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; @@ -92,7 +93,6 @@ import org.opensaml.messaging.context.MessageContext; import org.opensaml.messaging.decoder.MessageDecodingException; import org.opensaml.messaging.handler.MessageHandlerException; -import org.opensaml.saml.common.SAMLObject; import org.opensaml.saml.common.SAMLVersion; import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext; import org.opensaml.saml.common.messaging.context.SAMLProtocolContext; @@ -335,7 +335,7 @@ public String handleSsoGetRequestBase(HttpRequest request) { decoder.initialize(); decoder.decode(); - MessageContext messageContext = decoder.getMessageContext(); + MessageContext messageContext = decoder.getMessageContext(); if (!(messageContext.getMessage() instanceof AuthnRequest)) { throw new RuntimeException("Expected AuthnRequest; received: " + messageContext.getMessage()); @@ -369,7 +369,7 @@ public void handleSloGetRequestBase(HttpRequest request) { decoder.initialize(); decoder.decode(); - MessageContext messageContext = decoder.getMessageContext(); + MessageContext messageContext = decoder.getMessageContext(); if (!(messageContext.getMessage() instanceof LogoutRequest)) { throw new RuntimeException("Expected LogoutRequest; received: " + messageContext.getMessage()); @@ -415,18 +415,18 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { response.setVersion(SAMLVersion.VERSION_20); response.setStatus(createStatus(StatusCode.SUCCESS)); - response.setIssueInstant(new DateTime()); + response.setIssueInstant(Instant.now()); Assertion assertion = createSamlElement(Assertion.class); assertion.setID(nextId()); - assertion.setIssueInstant(new DateTime()); + assertion.setIssueInstant(Instant.now()); assertion.setIssuer(createIssuer()); AuthnStatement authnStatement = createSamlElement(AuthnStatement.class); assertion.getAuthnStatements().add(authnStatement); - authnStatement.setAuthnInstant(new DateTime()); + authnStatement.setAuthnInstant(Instant.now()); authnStatement.setSessionIndex(nextId()); authnStatement.setAuthnContext(createAuthnCotext()); @@ -440,7 +440,7 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { .add( createSubjectConfirmation( "urn:oasis:names:tc:SAML:2.0:cm:bearer", - new DateTime().plusMinutes(1), + Instant.now().plus(1, ChronoUnit.MINUTES), authnRequest.getID(), authnRequest.getAssertionConsumerServiceURL() ) @@ -450,7 +450,7 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { .add( createSubjectConfirmation( "urn:oasis:names:tc:SAML:2.0:cm:bearer", - new DateTime().plusMinutes(1), + Instant.now().plus(1, ChronoUnit.MINUTES), null, defaultAssertionConsumerService ) @@ -460,8 +460,8 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { Conditions conditions = createSamlElement(Conditions.class); assertion.setConditions(conditions); - conditions.setNotBefore(new DateTime()); - conditions.setNotOnOrAfter(new DateTime().plusMinutes(1)); + conditions.setNotBefore(Instant.now()); + conditions.setNotOnOrAfter(Instant.now().plus(1, ChronoUnit.MINUTES)); if (authenticateUserRoles != null) { AttributeStatement attributeStatement = createSamlElement(AttributeStatement.class); @@ -547,7 +547,7 @@ private NameIDFormat createNameIDFormat(String format) { NameIDFormat nameIdFormat = createSamlElement(NameIDFormat.class); - nameIdFormat.setFormat("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"); + nameIdFormat.setURI("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"); return nameIdFormat; } @@ -567,7 +567,7 @@ private NameID createNameID(String format, String value) { return nameID; } - private SubjectConfirmation createSubjectConfirmation(String method, DateTime notOnOrAfter, String inResponseTo, String recipient) { + private SubjectConfirmation createSubjectConfirmation(String method, Instant notOnOrAfter, String inResponseTo, String recipient) { SubjectConfirmation result = createSamlElement(SubjectConfirmation.class); result.setMethod(method); @@ -591,7 +591,7 @@ private Issuer createIssuer() { private AuthnContext createAuthnCotext() { AuthnContext authnContext = createSamlElement(AuthnContext.class); AuthnContextClassRef authnContextClassRef = createSamlElement(AuthnContextClassRef.class); - authnContextClassRef.setAuthnContextClassRef(AuthnContext.UNSPECIFIED_AUTHN_CTX); + authnContextClassRef.setURI(AuthnContext.UNSPECIFIED_AUTHN_CTX); authnContext.setAuthnContextClassRef(authnContextClassRef); return authnContext; }