From 8904361a3733c87410963945ba311619d5c7216e Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Tue, 31 Mar 2020 17:17:40 -0600 Subject: [PATCH] Polish Saml Tests Fixes gh-8403 Fixes gh-8404 --- .../Saml2WebSsoAuthenticationFilter.java | 1 - .../OpenSamlAuthenticationProviderTests.java | 308 +++++++----------- ...SamlAuthenticationRequestFactoryTests.java | 5 +- .../OpenSamlImplementationTests.java | 34 +- ...aml2AuthenticationRequestFactoryTests.java | 11 +- .../Saml2CryptoTestSupport.java | 169 ---------- .../authentication/TestOpenSamlObjects.java | 225 +++++++++++++ .../TestSaml2AuthenticationObjects.java | 112 ------- .../TestSaml2X509Credentials.java | 60 ++-- 9 files changed, 384 insertions(+), 541 deletions(-) delete mode 100644 saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2CryptoTestSupport.java create mode 100644 saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java delete mode 100644 saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2AuthenticationObjects.java diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java index 4fb2265aa1..2e3d9ddb95 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java @@ -117,5 +117,4 @@ public class Saml2WebSsoAuthenticationFilter extends AbstractAuthenticationProce return new String(b, UTF_8); } } - } diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java index 6faa0f4787..4c855933e4 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java @@ -19,17 +19,16 @@ package org.springframework.security.saml2.provider.service.authentication; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.util.Arrays; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.joda.time.DateTime; import org.joda.time.Duration; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.opensaml.core.xml.XMLObject; import org.opensaml.saml.saml2.core.Assertion; import org.opensaml.saml.saml2.core.EncryptedAssertion; import org.opensaml.saml.saml2.core.EncryptedID; @@ -37,15 +36,17 @@ import org.opensaml.saml.saml2.core.NameID; import org.opensaml.saml.saml2.core.Response; import org.springframework.security.core.Authentication; +import org.springframework.security.saml2.credentials.Saml2X509Credential; -import static java.util.Collections.emptyList; -import static org.springframework.security.saml2.provider.service.authentication.Saml2CryptoTestSupport.encryptAssertion; -import static org.springframework.security.saml2.provider.service.authentication.Saml2CryptoTestSupport.encryptNameId; -import static org.springframework.security.saml2.provider.service.authentication.Saml2CryptoTestSupport.signXmlObject; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2AuthenticationObjects.assertion; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2AuthenticationObjects.response; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.assertingPartyCredentials; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyCredentials; +import static org.springframework.security.saml2.provider.service.authentication.TestOpenSamlObjects.assertion; +import static org.springframework.security.saml2.provider.service.authentication.TestOpenSamlObjects.encrypted; +import static org.springframework.security.saml2.provider.service.authentication.TestOpenSamlObjects.response; +import static org.springframework.security.saml2.provider.service.authentication.TestOpenSamlObjects.signed; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.assertingPartyEncryptingCredential; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.assertingPartyPrivateCredential; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.assertingPartySigningCredential; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyDecryptingCredential; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyVerifyingCredential; import static org.springframework.test.util.AssertionErrors.assertTrue; import static org.springframework.util.StringUtils.hasText; @@ -57,37 +58,23 @@ import static org.springframework.util.StringUtils.hasText; */ public class OpenSamlAuthenticationProviderTests { - private static String username = "test@saml.user"; - private static String recipientUri = "https://localhost/login/saml2/sso/idp-alias"; - private static String recipientEntityId = "https://localhost/saml2/service-provider-metadata/idp-alias"; - private static String idpEntityId = "https://some.idp.test/saml2/idp"; + private static String DESTINATION = "https://localhost/login/saml2/sso/idp-alias"; + private static String RELYING_PARTY_ENTITY_ID = "https://localhost/saml2/service-provider-metadata/idp-alias"; + private static String ASSERTING_PARTY_ENTITY_ID = "https://some.idp.test/saml2/idp"; + + private OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider(); + private OpenSamlImplementation saml = OpenSamlImplementation.getInstance(); - private OpenSamlAuthenticationProvider provider; - private OpenSamlImplementation saml; - private Saml2AuthenticationToken token; @Rule public ExpectedException exception = ExpectedException.none(); - @Before - public void setup() { - this.saml = OpenSamlImplementation.getInstance(); - this.provider = new OpenSamlAuthenticationProvider(); - this.token = new Saml2AuthenticationToken( - "responseXml", - recipientUri, - idpEntityId, - recipientEntityId, - relyingPartyCredentials() - ); - } - @Test public void supportsWhenSaml2AuthenticationTokenThenReturnTrue() { assertTrue( - OpenSamlAuthenticationProvider.class + "should support " + this.token.getClass(), - this.provider.supports(this.token.getClass()) + OpenSamlAuthenticationProvider.class + "should support " + Saml2AuthenticationToken.class, + this.provider.supports(Saml2AuthenticationToken.class) ); } @@ -101,247 +88,191 @@ public class OpenSamlAuthenticationProviderTests { @Test public void authenticateWhenUnknownDataClassThenThrowAuthenticationException() { - Assertion assertion = defaultAssertion(); - this.token = responseXml(assertion); this.exception.expect(authenticationMatcher(Saml2ErrorCodes.UNKNOWN_RESPONSE_CLASS)); - this.provider.authenticate(this.token); + + Assertion assertion = this.saml.buildSamlObject(Assertion.DEFAULT_ELEMENT_NAME); + this.provider.authenticate(token(this.saml.serialize(assertion))); } @Test public void authenticateWhenXmlErrorThenThrowAuthenticationException() { - this.token = new Saml2AuthenticationToken( - "invalid xml string", - recipientUri, - idpEntityId, - recipientEntityId, - relyingPartyCredentials() - ); this.exception.expect(authenticationMatcher(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA)); - this.provider.authenticate(this.token); + + Saml2AuthenticationToken token = token("invalid xml"); + this.provider.authenticate(token); } @Test public void authenticateWhenInvalidDestinationThenThrowAuthenticationException() { - Response response = response(recipientUri + "invalid", idpEntityId); - this.token = responseXml(response); this.exception.expect(authenticationMatcher(Saml2ErrorCodes.INVALID_DESTINATION)); - this.provider.authenticate(this.token); + + Response response = response(DESTINATION + "invalid", ASSERTING_PARTY_ENTITY_ID); + response.getAssertions().add(assertion()); + signed(response, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenNoAssertionsPresentThenThrowAuthenticationException() { - Response response = response(recipientUri, idpEntityId); - this.token = responseXml(response); this.exception.expect( authenticationMatcher(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA, "No assertions found in response.") ); - this.provider.authenticate(this.token); + + Saml2AuthenticationToken token = token(response(), assertingPartySigningCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenInvalidSignatureOnAssertionThenThrowAuthenticationException() { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - response.getAssertions().add(assertion); - this.token = responseXml(response); this.exception.expect(authenticationMatcher(Saml2ErrorCodes.INVALID_SIGNATURE)); - this.provider.authenticate(this.token); + + Response response = response(); + response.getAssertions().add(assertion()); + Saml2AuthenticationToken token = token(response); + this.provider.authenticate(token); } @Test public void authenticateWhenOpenSAMLValidationErrorThenThrowAuthenticationException() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); + this.exception.expect(authenticationMatcher(Saml2ErrorCodes.INVALID_ASSERTION)); + + Response response = response(); + Assertion assertion = assertion(); assertion .getSubject() .getSubjectConfirmations() .get(0) .getSubjectConfirmationData() .setNotOnOrAfter(DateTime.now().minus(Duration.standardDays(3))); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); + signed(assertion, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); response.getAssertions().add(assertion); - this.token = responseXml(response); - - this.exception.expect(authenticationMatcher(Saml2ErrorCodes.INVALID_ASSERTION)); - this.provider.authenticate(this.token); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenMissingSubjectThenThrowAuthenticationException() { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - assertion.setSubject(null); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); - response.getAssertions().add(assertion); - this.token = responseXml(response); - this.exception.expect(authenticationMatcher(Saml2ErrorCodes.SUBJECT_NOT_FOUND)); + + Response response = response(); + Assertion assertion = assertion(); + assertion.setSubject(null); + signed(assertion, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); + response.getAssertions().add(assertion); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential()); this.provider.authenticate(token); } @Test public void authenticateWhenUsernameMissingThenThrowAuthenticationException() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); + this.exception.expect(authenticationMatcher(Saml2ErrorCodes.USERNAME_NOT_FOUND)); + + Response response = response(); + Assertion assertion = assertion(); assertion .getSubject() .getNameID() .setValue(null); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); + signed(assertion, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); response.getAssertions().add(assertion); - this.token = responseXml(response); - - this.exception.expect(authenticationMatcher(Saml2ErrorCodes.USERNAME_NOT_FOUND)); - this.provider.authenticate(this.token); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenAssertionContainsValidationAddressThenItSucceeds() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); + Response response = response(); + Assertion assertion = assertion(); assertion.getSubject().getSubjectConfirmations().forEach( sc -> sc.getSubjectConfirmationData().setAddress("10.10.10.10") ); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); + signed(assertion, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); response.getAssertions().add(assertion); - this.token = responseXml(response); - this.provider.authenticate(this.token); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenEncryptedAssertionWithoutSignatureThenItFails() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials()); - response.getEncryptedAssertions().add(encryptedAssertion); - this.token = responseXml(response); this.exception.expect(authenticationMatcher(Saml2ErrorCodes.INVALID_SIGNATURE)); - this.provider.authenticate(this.token); + + Response response = response(); + EncryptedAssertion encryptedAssertion = encrypted(assertion(), assertingPartyEncryptingCredential()); + response.getEncryptedAssertions().add(encryptedAssertion); + Saml2AuthenticationToken token = token(response, relyingPartyDecryptingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenEncryptedAssertionWithSignatureThenItSucceeds() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); - EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials()); + Response response = response(); + Assertion assertion = signed(assertion(), assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); + EncryptedAssertion encryptedAssertion = encrypted(assertion, assertingPartyEncryptingCredential()); response.getEncryptedAssertions().add(encryptedAssertion); - this.token = responseXml(response); - this.provider.authenticate(this.token); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential(), relyingPartyDecryptingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenEncryptedAssertionWithResponseSignatureThenItSucceeds() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials()); + Response response = response(); + EncryptedAssertion encryptedAssertion = encrypted(assertion(), assertingPartyEncryptingCredential()); response.getEncryptedAssertions().add(encryptedAssertion); - signXmlObject( - response, - assertingPartyCredentials(), - recipientEntityId - ); - this.token = responseXml(response); - provider.authenticate(this.token); + signed(response, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential(), relyingPartyDecryptingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenEncryptedNameIdWithSignatureThenItSucceeds() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); + Response response = response(); + Assertion assertion = assertion(); NameID nameId = assertion.getSubject().getNameID(); - EncryptedID encryptedID = encryptNameId(nameId, assertingPartyCredentials()); + EncryptedID encryptedID = encrypted(nameId, assertingPartyEncryptingCredential()); assertion.getSubject().setNameID(null); assertion.getSubject().setEncryptedID(encryptedID); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); response.getAssertions().add(assertion); - this.token = responseXml(response); - this.provider.authenticate(this.token); + signed(assertion, assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential(), relyingPartyDecryptingCredential()); + this.provider.authenticate(token); } @Test public void authenticateWhenDecryptionKeysAreMissingThenThrowAuthenticationException() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials()); - response.getEncryptedAssertions().add(encryptedAssertion); - this.token = responseXml(response); - - this.token = new Saml2AuthenticationToken( - this.token.getSaml2Response(), - recipientUri, - idpEntityId, - recipientEntityId, - emptyList() - ); - this.exception.expect( authenticationMatcher(Saml2ErrorCodes.DECRYPTION_ERROR, "No valid decryption credentials found.") ); - this.provider.authenticate(this.token); + + Response response = response(); + EncryptedAssertion encryptedAssertion = encrypted(assertion(), assertingPartyEncryptingCredential()); + response.getEncryptedAssertions().add(encryptedAssertion); + Saml2AuthenticationToken token = token(this.saml.serialize(response)); + this.provider.authenticate(token); } @Test public void authenticateWhenDecryptionKeysAreWrongThenThrowAuthenticationException() throws Exception { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials()); - response.getEncryptedAssertions().add(encryptedAssertion); - this.token = responseXml(response); - - this.token = new Saml2AuthenticationToken( - this.token.getSaml2Response(), - recipientUri, - idpEntityId, - recipientEntityId, - assertingPartyCredentials() - ); - this.exception.expect( authenticationMatcher(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData") ); - this.provider.authenticate(this.token); + + Response response = response(); + EncryptedAssertion encryptedAssertion = encrypted(assertion(), assertingPartyEncryptingCredential()); + response.getEncryptedAssertions().add(encryptedAssertion); + Saml2AuthenticationToken token = token(this.saml.serialize(response), assertingPartyPrivateCredential()); + this.provider.authenticate(token); } @Test public void writeObjectWhenTypeIsSaml2AuthenticationThenNoException() throws IOException { - Response response = response(recipientUri, idpEntityId); - Assertion assertion = defaultAssertion(); - signXmlObject( - assertion, - assertingPartyCredentials(), - recipientEntityId - ); - EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials()); + Response response = response(); + Assertion assertion = signed(assertion(), assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID); + EncryptedAssertion encryptedAssertion = encrypted(assertion, assertingPartyEncryptingCredential()); response.getEncryptedAssertions().add(encryptedAssertion); - this.token = responseXml(response); - - Saml2Authentication authentication = (Saml2Authentication) this.provider.authenticate(this.token); + Saml2AuthenticationToken token = token(response, relyingPartyVerifyingCredential(), relyingPartyDecryptingCredential()); + Saml2Authentication authentication = (Saml2Authentication) this.provider.authenticate(token); // the following code will throw an exception if authentication isn't serializable ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024); @@ -350,27 +281,6 @@ public class OpenSamlAuthenticationProviderTests { objectOutputStream.flush(); } - private Assertion defaultAssertion() { - return assertion( - username, - idpEntityId, - recipientEntityId, - recipientUri - ); - } - - private Saml2AuthenticationToken responseXml(XMLObject assertion) { - String xml = this.saml.serialize(assertion); - return new Saml2AuthenticationToken( - xml, - recipientUri, - idpEntityId, - recipientEntityId, - relyingPartyCredentials() - ); - - } - private Matcher authenticationMatcher(String code) { return authenticationMatcher(code, null); } @@ -402,4 +312,14 @@ public class OpenSamlAuthenticationProviderTests { } }; } + + private Saml2AuthenticationToken token(Response response, Saml2X509Credential... credentials) { + String payload = this.saml.serialize(response); + return token(payload, credentials); + } + + private Saml2AuthenticationToken token(String payload, Saml2X509Credential... credentials) { + return new Saml2AuthenticationToken(payload, + DESTINATION, ASSERTING_PARTY_ENTITY_ID, RELYING_PARTY_ENTITY_ID, Arrays.asList(credentials)); + } } diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationRequestFactoryTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationRequestFactoryTests.java index a795538f50..f93a02f1c5 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationRequestFactoryTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationRequestFactoryTests.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.saml2.core.AuthnRequest; + import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding; @@ -30,7 +31,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.containsString; import static org.springframework.security.saml2.provider.service.authentication.Saml2Utils.samlDecode; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyCredentials; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartySigningCredential; import static org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration.withRelyingPartyRegistration; import static org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding.POST; import static org.springframework.security.saml2.provider.service.registration.Saml2MessageBinding.REDIRECT; @@ -55,7 +56,7 @@ public class OpenSamlAuthenticationRequestFactoryTests { .providerDetails(c -> c.webSsoUrl("https://destination/sso")) .providerDetails(c -> c.entityId("remote-entity-id")) .localEntityIdTemplate("local-entity-id") - .credentials(c -> c.addAll(relyingPartyCredentials())) + .credentials(c -> c.add(relyingPartySigningCredential())) .build(); contextBuilder = Saml2AuthenticationRequestContext.builder() .issuer("https://issuer") diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlImplementationTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlImplementationTests.java index b142c24b07..10dfe13a4e 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlImplementationTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlImplementationTests.java @@ -16,24 +16,22 @@ package org.springframework.security.saml2.provider.service.authentication; +import java.util.Arrays; +import java.util.Map; + import org.junit.Test; -import org.opensaml.security.credential.BasicCredential; -import org.opensaml.security.credential.Credential; -import org.opensaml.security.credential.CredentialSupport; -import org.opensaml.security.credential.UsageType; import org.opensaml.xmlsec.crypto.XMLSigningUtil; + import org.springframework.security.saml2.credentials.Saml2X509Credential; import org.springframework.web.util.UriUtils; -import java.util.List; -import java.util.Map; - import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.opensaml.xmlsec.signature.support.SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.assertingPartyCredentials; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyCredentials; +import static org.springframework.security.saml2.provider.service.authentication.TestOpenSamlObjects.getSigningCredential; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.assertingPartySigningCredential; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyVerifyingCredential; public class OpenSamlImplementationTests { @@ -45,12 +43,12 @@ public class OpenSamlImplementationTests { @Test public void signQueryParametersWhenDataSuppliedReturnsValidSignature() throws Exception { OpenSamlImplementation impl = OpenSamlImplementation.getInstance(); - List signCredentials = relyingPartyCredentials(); - List verifyCredentials = assertingPartyCredentials(); + Saml2X509Credential signingCredential = assertingPartySigningCredential(); + Saml2X509Credential verifyingCredential = relyingPartyVerifyingCredential(); String samlRequest = "saml-request-example"; String encoded = Saml2Utils.samlEncode(samlRequest.getBytes(UTF_8)); String relayState = "test relay state"; - Map parameters = impl.signQueryParameters(signCredentials, encoded, relayState); + Map parameters = impl.signQueryParameters(Arrays.asList(signingCredential), encoded, relayState); String queryString = "SAMLRequest=" + UriUtils.encode(encoded, ISO_8859_1) + @@ -62,21 +60,11 @@ public class OpenSamlImplementationTests { byte[] signature = Saml2Utils.samlDecode(parameters.get("Signature")); boolean result = XMLSigningUtil.verifyWithURI( - getOpenSamlCredential(verifyCredentials.get(1), "local-sp-entity-id", UsageType.SIGNING), + getSigningCredential(verifyingCredential, "local-sp-entity-id"), ALGO_ID_SIGNATURE_RSA_SHA256, signature, queryString.getBytes(UTF_8) ); assertThat(result).isTrue(); } - - private Credential getOpenSamlCredential(Saml2X509Credential credential, String localSpEntityId, UsageType usageType) { - BasicCredential cred = CredentialSupport.getSimpleCredential( - credential.getCertificate(), - credential.getPrivateKey() - ); - cred.setEntityId(localSpEntityId); - cred.setUsageType(usageType); - return cred; - } } diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2AuthenticationRequestFactoryTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2AuthenticationRequestFactoryTests.java index 7b66577fbf..97cf81a220 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2AuthenticationRequestFactoryTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2AuthenticationRequestFactoryTests.java @@ -16,15 +16,16 @@ package org.springframework.security.saml2.provider.service.authentication; -import org.junit.Test; -import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; - import java.util.UUID; +import org.junit.Test; + +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; + import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.security.saml2.provider.service.authentication.Saml2Utils.samlDecode; import static org.springframework.security.saml2.provider.service.authentication.Saml2Utils.samlInflate; -import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartyCredentials; +import static org.springframework.security.saml2.provider.service.authentication.TestSaml2X509Credentials.relyingPartySigningCredential; /** * Tests for {@link Saml2AuthenticationRequestFactory} default interface methods @@ -36,7 +37,7 @@ public class Saml2AuthenticationRequestFactoryTests { .providerDetails(c -> c.webSsoUrl("https://example.com/destination")) .providerDetails(c -> c.entityId("remote-entity-id")) .localEntityIdTemplate("local-entity-id") - .credentials(c -> c.addAll(relyingPartyCredentials())) + .credentials(c -> c.add(relyingPartySigningCredential())) .build(); @Test diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2CryptoTestSupport.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2CryptoTestSupport.java deleted file mode 100644 index 29cdf8aae2..0000000000 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/Saml2CryptoTestSupport.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2002-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.saml2.provider.service.authentication; - -import org.springframework.security.saml2.Saml2Exception; -import org.springframework.security.saml2.credentials.Saml2X509Credential; - -import org.apache.xml.security.algorithms.JCEMapper; -import org.apache.xml.security.encryption.XMLCipherParameters; -import org.opensaml.core.xml.io.MarshallingException; -import org.opensaml.saml.common.SignableSAMLObject; -import org.opensaml.saml.saml2.core.Assertion; -import org.opensaml.saml.saml2.core.EncryptedAssertion; -import org.opensaml.saml.saml2.core.EncryptedID; -import org.opensaml.saml.saml2.core.NameID; -import org.opensaml.saml.saml2.encryption.Encrypter; -import org.opensaml.security.SecurityException; -import org.opensaml.security.credential.BasicCredential; -import org.opensaml.security.credential.Credential; -import org.opensaml.security.credential.CredentialSupport; -import org.opensaml.security.credential.UsageType; -import org.opensaml.security.x509.BasicX509Credential; -import org.opensaml.xmlsec.SignatureSigningParameters; -import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters; -import org.opensaml.xmlsec.encryption.support.EncryptionException; -import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters; -import org.opensaml.xmlsec.signature.support.SignatureConstants; -import org.opensaml.xmlsec.signature.support.SignatureException; -import org.opensaml.xmlsec.signature.support.SignatureSupport; - -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.cert.X509Certificate; -import java.util.List; -import javax.crypto.SecretKey; - -import static java.util.Arrays.asList; -import static org.opensaml.security.crypto.KeySupport.generateKey; - -final class Saml2CryptoTestSupport { - static void signXmlObject(SignableSAMLObject object, List signingCredentials, String entityId) { - SignatureSigningParameters parameters = new SignatureSigningParameters(); - Credential credential = getSigningCredential(signingCredentials, entityId); - parameters.setSigningCredential(credential); - parameters.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - parameters.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256); - parameters.setSignatureCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - try { - SignatureSupport.signObject(object, parameters); - } catch (MarshallingException | SignatureException | SecurityException e) { - throw new Saml2Exception(e); - } - - } - - static EncryptedAssertion encryptAssertion(Assertion assertion, List encryptionCredentials) { - X509Certificate certificate = getEncryptionCertificate(encryptionCredentials); - Encrypter encrypter = getEncrypter(certificate); - try { - Encrypter.KeyPlacement keyPlacement = Encrypter.KeyPlacement.valueOf("PEER"); - encrypter.setKeyPlacement(keyPlacement); - return encrypter.encrypt(assertion); - } - catch (EncryptionException e) { - throw new Saml2Exception("Unable to encrypt assertion.", e); - } - } - - static EncryptedID encryptNameId(NameID nameID, List encryptionCredentials) { - X509Certificate certificate = getEncryptionCertificate(encryptionCredentials); - Encrypter encrypter = getEncrypter(certificate); - try { - Encrypter.KeyPlacement keyPlacement = Encrypter.KeyPlacement.valueOf("PEER"); - encrypter.setKeyPlacement(keyPlacement); - return encrypter.encrypt(nameID); - } - catch (EncryptionException e) { - throw new Saml2Exception("Unable to encrypt nameID.", e); - } - } - - private static Encrypter getEncrypter(X509Certificate certificate) { - Credential credential = CredentialSupport.getSimpleCredential(certificate, null); - final String dataAlgorithm = XMLCipherParameters.AES_256; - final String keyAlgorithm = XMLCipherParameters.RSA_1_5; - SecretKey secretKey = generateKeyFromURI(dataAlgorithm); - BasicCredential dataCredential = new BasicCredential(secretKey); - DataEncryptionParameters dataEncryptionParameters = new DataEncryptionParameters(); - dataEncryptionParameters.setEncryptionCredential(dataCredential); - dataEncryptionParameters.setAlgorithm(dataAlgorithm); - - KeyEncryptionParameters keyEncryptionParameters = new KeyEncryptionParameters(); - keyEncryptionParameters.setEncryptionCredential(credential); - keyEncryptionParameters.setAlgorithm(keyAlgorithm); - - Encrypter encrypter = new Encrypter(dataEncryptionParameters, asList(keyEncryptionParameters)); - - return encrypter; - } - - private static SecretKey generateKeyFromURI(String algoURI) { - try { - String jceAlgorithmName = JCEMapper.getJCEKeyAlgorithmFromURI(algoURI); - int keyLength = JCEMapper.getKeyLengthFromURI(algoURI); - return generateKey(jceAlgorithmName, keyLength, null); - } - catch (NoSuchAlgorithmException | NoSuchProviderException e) { - throw new Saml2Exception(e); - } - } - - private static X509Certificate getEncryptionCertificate(List encryptionCredentials) { - X509Certificate certificate = null; - for (Saml2X509Credential credential : encryptionCredentials) { - if (credential.isEncryptionCredential()) { - certificate = credential.getCertificate(); - break; - } - } - if (certificate == null) { - throw new Saml2Exception("No valid encryption certificate found"); - } - return certificate; - } - - private static Saml2X509Credential hasSigningCredential(List credentials) { - for (Saml2X509Credential c : credentials) { - if (c.isSigningCredential()) { - return c; - } - } - return null; - } - - private static Credential getSigningCredential(List signingCredential, - String localSpEntityId - ) { - Saml2X509Credential credential = hasSigningCredential(signingCredential); - if (credential == null) { - throw new Saml2Exception("no signing credential configured"); - } - BasicCredential cred = getBasicCredential(credential); - cred.setEntityId(localSpEntityId); - cred.setUsageType(UsageType.SIGNING); - return cred; - } - - private static BasicX509Credential getBasicCredential(Saml2X509Credential credential) { - return CredentialSupport.getSimpleCredential( - credential.getCertificate(), - credential.getPrivateKey() - ); - } - -} diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java new file mode 100644 index 0000000000..27d0d73129 --- /dev/null +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestOpenSamlObjects.java @@ -0,0 +1,225 @@ +/* + * Copyright 2002-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.saml2.provider.service.authentication; + +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.UUID; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.xml.security.encryption.XMLCipherParameters; +import org.joda.time.DateTime; +import org.joda.time.Duration; +import org.opensaml.core.xml.io.MarshallingException; +import org.opensaml.saml.common.SAMLVersion; +import org.opensaml.saml.common.SignableSAMLObject; +import org.opensaml.saml.saml2.core.Assertion; +import org.opensaml.saml.saml2.core.Conditions; +import org.opensaml.saml.saml2.core.EncryptedAssertion; +import org.opensaml.saml.saml2.core.EncryptedID; +import org.opensaml.saml.saml2.core.Issuer; +import org.opensaml.saml.saml2.core.NameID; +import org.opensaml.saml.saml2.core.Response; +import org.opensaml.saml.saml2.core.Subject; +import org.opensaml.saml.saml2.core.SubjectConfirmation; +import org.opensaml.saml.saml2.core.SubjectConfirmationData; +import org.opensaml.saml.saml2.encryption.Encrypter; +import org.opensaml.security.SecurityException; +import org.opensaml.security.credential.BasicCredential; +import org.opensaml.security.credential.Credential; +import org.opensaml.security.credential.CredentialSupport; +import org.opensaml.security.credential.UsageType; +import org.opensaml.xmlsec.SignatureSigningParameters; +import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters; +import org.opensaml.xmlsec.encryption.support.EncryptionException; +import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters; +import org.opensaml.xmlsec.signature.support.SignatureConstants; +import org.opensaml.xmlsec.signature.support.SignatureException; +import org.opensaml.xmlsec.signature.support.SignatureSupport; + +import org.springframework.security.saml2.Saml2Exception; +import org.springframework.security.saml2.credentials.Saml2X509Credential; + +final class TestOpenSamlObjects { + private static OpenSamlImplementation saml = OpenSamlImplementation.getInstance(); + + private static String USERNAME = "test@saml.user"; + private static String DESTINATION = "https://localhost/login/saml2/sso/idp-alias"; + private static String RELYING_PARTY_ENTITY_ID = "https://localhost/saml2/service-provider-metadata/idp-alias"; + private static String ASSERTING_PARTY_ENTITY_ID = "https://some.idp.test/saml2/idp"; + private static SecretKey SECRET_KEY = + new SecretKeySpec(Base64.getDecoder().decode("shOnwNMoCv88HKMEa91+FlYoD5RNvzMTAL5LGxZKIFk="), "AES"); + + static Response response() { + return response(DESTINATION, ASSERTING_PARTY_ENTITY_ID); + } + + static Response response(String destination, String issuerEntityId) { + Response response = saml.buildSamlObject(Response.DEFAULT_ELEMENT_NAME); + response.setID("R"+UUID.randomUUID().toString()); + response.setIssueInstant(DateTime.now()); + response.setVersion(SAMLVersion.VERSION_20); + response.setID("_" + UUID.randomUUID().toString()); + response.setDestination(destination); + response.setIssuer(issuer(issuerEntityId)); + return response; + } + + static Assertion assertion() { + return assertion(USERNAME, ASSERTING_PARTY_ENTITY_ID, RELYING_PARTY_ENTITY_ID, DESTINATION); + } + + static Assertion assertion( + String username, + String issuerEntityId, + String recipientEntityId, + String recipientUri + ) { + Assertion assertion = saml.buildSamlObject(Assertion.DEFAULT_ELEMENT_NAME); + assertion.setID("A"+ UUID.randomUUID().toString()); + assertion.setIssueInstant(DateTime.now()); + assertion.setVersion(SAMLVersion.VERSION_20); + assertion.setIssueInstant(DateTime.now()); + assertion.setIssuer(issuer(issuerEntityId)); + assertion.setSubject(subject(username)); + assertion.setConditions(conditions()); + + SubjectConfirmation subjectConfirmation = subjectConfirmation(); + subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); + SubjectConfirmationData confirmationData = subjectConfirmationData(recipientEntityId); + confirmationData.setRecipient(recipientUri); + subjectConfirmation.setSubjectConfirmationData(confirmationData); + assertion.getSubject().getSubjectConfirmations().add(subjectConfirmation); + return assertion; + } + + + static Issuer issuer(String entityId) { + Issuer issuer = saml.buildSamlObject(Issuer.DEFAULT_ELEMENT_NAME); + issuer.setValue(entityId); + return issuer; + } + + static Subject subject(String principalName) { + Subject subject = saml.buildSamlObject(Subject.DEFAULT_ELEMENT_NAME); + + if (principalName != null) { + subject.setNameID(nameId(principalName)); + } + + return subject; + } + + static NameID nameId(String principalName) { + NameID nameId = saml.buildSamlObject(NameID.DEFAULT_ELEMENT_NAME); + nameId.setValue(principalName); + return nameId; + } + + static SubjectConfirmation subjectConfirmation() { + return saml.buildSamlObject(SubjectConfirmation.DEFAULT_ELEMENT_NAME); + } + + static SubjectConfirmationData subjectConfirmationData(String recipient) { + SubjectConfirmationData subject = saml.buildSamlObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME); + subject.setRecipient(recipient); + subject.setNotBefore(DateTime.now().minus(Duration.millis(5 * 60 * 1000))); + subject.setNotOnOrAfter(DateTime.now().plus(Duration.millis(5 * 60 * 1000))); + return subject; + } + + static Conditions conditions() { + Conditions conditions = saml.buildSamlObject(Conditions.DEFAULT_ELEMENT_NAME); + conditions.setNotBefore(DateTime.now().minus(Duration.millis(5 * 60 * 1000))); + conditions.setNotOnOrAfter(DateTime.now().plus(Duration.millis(5 * 60 * 1000))); + return conditions; + } + + static Credential getSigningCredential(Saml2X509Credential credential, String entityId) { + BasicCredential cred = getBasicCredential(credential); + cred.setEntityId(entityId); + cred.setUsageType(UsageType.SIGNING); + return cred; + } + + static BasicCredential getBasicCredential(Saml2X509Credential credential) { + return CredentialSupport.getSimpleCredential( + credential.getCertificate(), + credential.getPrivateKey() + ); + } + + static T signed(T signable, Saml2X509Credential credential, String entityId) { + SignatureSigningParameters parameters = new SignatureSigningParameters(); + Credential signingCredential = getSigningCredential(credential, entityId); + parameters.setSigningCredential(signingCredential); + parameters.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + parameters.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256); + parameters.setSignatureCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + try { + SignatureSupport.signObject(signable, parameters); + } catch (MarshallingException | SignatureException | SecurityException e) { + throw new Saml2Exception(e); + } + + return signable; + } + + static EncryptedAssertion encrypted(Assertion assertion, Saml2X509Credential credential) { + X509Certificate certificate = credential.getCertificate(); + Encrypter encrypter = getEncrypter(certificate); + try { + return encrypter.encrypt(assertion); + } + catch (EncryptionException e) { + throw new Saml2Exception("Unable to encrypt assertion.", e); + } + } + + static EncryptedID encrypted(NameID nameId, Saml2X509Credential credential) { + X509Certificate certificate = credential.getCertificate(); + Encrypter encrypter = getEncrypter(certificate); + try { + return encrypter.encrypt(nameId); + } + catch (EncryptionException e) { + throw new Saml2Exception("Unable to encrypt nameID.", e); + } + } + + private static Encrypter getEncrypter(X509Certificate certificate) { + String dataAlgorithm = XMLCipherParameters.AES_256; + String keyAlgorithm = XMLCipherParameters.RSA_1_5; + + BasicCredential dataCredential = new BasicCredential(SECRET_KEY); + DataEncryptionParameters dataEncryptionParameters = new DataEncryptionParameters(); + dataEncryptionParameters.setEncryptionCredential(dataCredential); + dataEncryptionParameters.setAlgorithm(dataAlgorithm); + + Credential credential = CredentialSupport.getSimpleCredential(certificate, null); + KeyEncryptionParameters keyEncryptionParameters = new KeyEncryptionParameters(); + keyEncryptionParameters.setEncryptionCredential(credential); + keyEncryptionParameters.setAlgorithm(keyAlgorithm); + + Encrypter encrypter = new Encrypter(dataEncryptionParameters, keyEncryptionParameters); + Encrypter.KeyPlacement keyPlacement = Encrypter.KeyPlacement.valueOf("PEER"); + encrypter.setKeyPlacement(keyPlacement); + + return encrypter; + } +} diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2AuthenticationObjects.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2AuthenticationObjects.java deleted file mode 100644 index d0a2a4f553..0000000000 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2AuthenticationObjects.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.security.saml2.provider.service.authentication; - -import java.util.UUID; - -import org.joda.time.DateTime; -import org.joda.time.Duration; -import org.opensaml.saml.common.SAMLVersion; -import org.opensaml.saml.saml2.core.Assertion; -import org.opensaml.saml.saml2.core.Conditions; -import org.opensaml.saml.saml2.core.Issuer; -import org.opensaml.saml.saml2.core.NameID; -import org.opensaml.saml.saml2.core.Response; -import org.opensaml.saml.saml2.core.Subject; -import org.opensaml.saml.saml2.core.SubjectConfirmation; -import org.opensaml.saml.saml2.core.SubjectConfirmationData; - -final class TestSaml2AuthenticationObjects { - private static OpenSamlImplementation saml = OpenSamlImplementation.getInstance(); - - static Response response(String destination, String issuerEntityId) { - Response response = saml.buildSamlObject(Response.DEFAULT_ELEMENT_NAME); - response.setID("R"+UUID.randomUUID().toString()); - response.setIssueInstant(DateTime.now()); - response.setVersion(SAMLVersion.VERSION_20); - response.setID("_" + UUID.randomUUID().toString()); - response.setDestination(destination); - response.setIssuer(issuer(issuerEntityId)); - return response; - } - static Assertion assertion( - String username, - String issuerEntityId, - String recipientEntityId, - String recipientUri - ) { - Assertion assertion = saml.buildSamlObject(Assertion.DEFAULT_ELEMENT_NAME); - assertion.setID("A"+ UUID.randomUUID().toString()); - assertion.setIssueInstant(DateTime.now()); - assertion.setVersion(SAMLVersion.VERSION_20); - assertion.setIssueInstant(DateTime.now()); - assertion.setIssuer(issuer(issuerEntityId)); - assertion.setSubject(subject(username)); - assertion.setConditions(conditions()); - - SubjectConfirmation subjectConfirmation = subjectConfirmation(); - subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER); - SubjectConfirmationData confirmationData = subjectConfirmationData(recipientEntityId); - confirmationData.setRecipient(recipientUri); - subjectConfirmation.setSubjectConfirmationData(confirmationData); - assertion.getSubject().getSubjectConfirmations().add(subjectConfirmation); - return assertion; - } - - - static Issuer issuer(String entityId) { - Issuer issuer = saml.buildSamlObject(Issuer.DEFAULT_ELEMENT_NAME); - issuer.setValue(entityId); - return issuer; - } - - static Subject subject(String principalName) { - Subject subject = saml.buildSamlObject(Subject.DEFAULT_ELEMENT_NAME); - - if (principalName != null) { - subject.setNameID(nameId(principalName)); - } - - return subject; - } - - static NameID nameId(String principalName) { - NameID nameId = saml.buildSamlObject(NameID.DEFAULT_ELEMENT_NAME); - nameId.setValue(principalName); - return nameId; - } - - static SubjectConfirmation subjectConfirmation() { - return saml.buildSamlObject(SubjectConfirmation.DEFAULT_ELEMENT_NAME); - } - - static SubjectConfirmationData subjectConfirmationData(String recipient) { - SubjectConfirmationData subject = saml.buildSamlObject(SubjectConfirmationData.DEFAULT_ELEMENT_NAME); - subject.setRecipient(recipient); - subject.setNotBefore(DateTime.now().minus(Duration.millis(5 * 60 * 1000))); - subject.setNotOnOrAfter(DateTime.now().plus(Duration.millis(5 * 60 * 1000))); - return subject; - } - - static Conditions conditions() { - Conditions conditions = saml.buildSamlObject(Conditions.DEFAULT_ELEMENT_NAME); - conditions.setNotBefore(DateTime.now().minus(Duration.millis(5 * 60 * 1000))); - conditions.setNotOnOrAfter(DateTime.now().plus(Duration.millis(5 * 60 * 1000))); - return conditions; - } - -} diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2X509Credentials.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2X509Credentials.java index faef9743b5..f93e96aea8 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2X509Credentials.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/TestSaml2X509Credentials.java @@ -16,19 +16,17 @@ package org.springframework.security.saml2.provider.service.authentication; -import org.springframework.security.saml2.Saml2Exception; -import org.springframework.security.saml2.credentials.Saml2X509Credential; - -import org.opensaml.security.crypto.KeySupport; - import java.io.ByteArrayInputStream; import java.security.KeyException; import java.security.PrivateKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.List; + +import org.opensaml.security.crypto.KeySupport; + +import org.springframework.security.saml2.Saml2Exception; +import org.springframework.security.saml2.credentials.Saml2X509Credential; import static java.nio.charset.StandardCharsets.UTF_8; import static org.springframework.security.saml2.credentials.Saml2X509Credential.Saml2X509CredentialType.DECRYPTION; @@ -37,36 +35,28 @@ import static org.springframework.security.saml2.credentials.Saml2X509Credential import static org.springframework.security.saml2.credentials.Saml2X509Credential.Saml2X509CredentialType.VERIFICATION; final class TestSaml2X509Credentials { - static List assertingPartyCredentials() { - return Arrays.asList( - new Saml2X509Credential( - idpPrivateKey(), - idpCertificate(), - SIGNING, - DECRYPTION - ), - new Saml2X509Credential( - spCertificate(), - ENCRYPTION, - VERIFICATION - ) - ); + static Saml2X509Credential assertingPartySigningCredential() { + return new Saml2X509Credential(idpPrivateKey(), idpCertificate(), SIGNING); } - static List relyingPartyCredentials() { - return Arrays.asList( - new Saml2X509Credential( - spPrivateKey(), - spCertificate(), - SIGNING, - DECRYPTION - ), - new Saml2X509Credential( - idpCertificate(), - ENCRYPTION, - VERIFICATION - ) - ); + static Saml2X509Credential assertingPartyEncryptingCredential() { + return new Saml2X509Credential(spCertificate(), ENCRYPTION); + } + + static Saml2X509Credential assertingPartyPrivateCredential() { + return new Saml2X509Credential(idpPrivateKey(), idpCertificate(), SIGNING, DECRYPTION); + } + + static Saml2X509Credential relyingPartyVerifyingCredential() { + return new Saml2X509Credential(idpCertificate(), VERIFICATION); + } + + static Saml2X509Credential relyingPartySigningCredential() { + return new Saml2X509Credential(spPrivateKey(), spCertificate(), SIGNING); + } + + static Saml2X509Credential relyingPartyDecryptingCredential() { + return new Saml2X509Credential(spPrivateKey(), spCertificate(), DECRYPTION); } private static X509Certificate certificate(String cert) {