瀏覽代碼

Always require signature on either response or assertion

Fixes gh-7490
https://github.com/spring-projects/spring-security/issues/7490
Filip Hanik 5 年之前
父節點
當前提交
7adb4da3ef

+ 1 - 1
saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProvider.java

@@ -254,7 +254,7 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
 			}
 			try {
 				Assertion a = decrypt(token, ea);
-				validateAssertion(recipient, a, token, false);
+				validateAssertion(recipient, a, token, !responseSigned);
 				return a;
 			} catch (Saml2AuthenticationException e) {
 				lastValidationError = e;

+ 36 - 1
saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java

@@ -216,12 +216,47 @@ public class OpenSamlAuthenticationProviderTests {
 	}
 
 	@Test
-	public void authenticateWhenEncryptedAssertionWithoutSignatureThenItSucceeds() throws Exception {
+	public void authenticateWhenEncryptedAssertionWithoutSignatureThenItFails() throws Exception {
 		Response response = response(recipientUri, idpEntityId);
 		Assertion assertion = defaultAssertion();
 		EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials());
 		response.getEncryptedAssertions().add(encryptedAssertion);
 		token = responseXml(response, idpEntityId);
+		exception.expect(
+				authenticationMatcher(
+						Saml2ErrorCodes.INVALID_SIGNATURE
+				)
+		);
+		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.getEncryptedAssertions().add(encryptedAssertion);
+		token = responseXml(response, idpEntityId);
+		provider.authenticate(token);
+	}
+
+	@Test
+	public void authenticateWhenEncryptedAssertionWithResponseSignatureThenItSucceeds() throws Exception {
+		Response response = response(recipientUri, idpEntityId);
+		Assertion assertion = defaultAssertion();
+		EncryptedAssertion encryptedAssertion = encryptAssertion(assertion, assertingPartyCredentials());
+		response.getEncryptedAssertions().add(encryptedAssertion);
+		signXmlObject(
+				response,
+				assertingPartyCredentials(),
+				recipientEntityId
+		);
+		token = responseXml(response, idpEntityId);
 		provider.authenticate(token);
 	}
 

+ 3 - 2
samples/boot/saml2login/src/integration-test/java/org/springframework/security/samples/Saml2LoginIntegrationTests.java

@@ -163,14 +163,15 @@ public class Saml2LoginIntegrationTests {
 		EncryptedAssertion encryptedAssertion =
 				OpenSamlActionTestingSupport.encryptAssertion(assertion, decodeCertificate(spCertificate));
 		Response response = buildResponse(encryptedAssertion);
-		signXmlObject(assertion, getSigningCredential(idpCertificate, idpPrivateKey, UsageType.SIGNING));
+		signXmlObject(response, getSigningCredential(idpCertificate, idpPrivateKey, UsageType.SIGNING));
 		sendResponse(response, "/")
 				.andExpect(authenticated().withUsername(USERNAME));
 	}
 
 	@Test
-	public void authenticateWhenResponseIsNotSignedAndAssertionIsEncryptedThenItSucceeds() throws Exception {
+	public void authenticateWhenResponseIsNotSignedAndAssertionIsEncryptedAndSignedThenItSucceeds() throws Exception {
 		Assertion assertion = buildAssertion(USERNAME);
+		signXmlObject(assertion, getSigningCredential(idpCertificate, idpPrivateKey, UsageType.SIGNING));
 		EncryptedAssertion encryptedAssertion =
 				OpenSamlActionTestingSupport.encryptAssertion(assertion, decodeCertificate(spCertificate));
 		Response response = buildResponse(encryptedAssertion);