浏览代码

Read SigningMethod Elements

Closes gh-9177
Josh Cummings 4 年之前
父节点
当前提交
aba0e904f0

+ 25 - 0
saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/OpenSamlAssertingPartyMetadataConverter.java

@@ -28,8 +28,10 @@ import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
 import org.opensaml.core.xml.io.Unmarshaller;
 import org.opensaml.saml.common.xml.SAMLConstants;
+import org.opensaml.saml.ext.saml2alg.SigningMethod;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.Extensions;
 import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.KeyDescriptor;
 import org.opensaml.saml.saml2.metadata.SingleSignOnService;
@@ -98,6 +100,11 @@ class OpenSamlAssertingPartyMetadataConverter {
 						.wantAuthnRequestsSigned(Boolean.TRUE.equals(idpssoDescriptor.getWantAuthnRequestsSigned()))
 						.verificationX509Credentials((c) -> c.addAll(verification))
 						.encryptionX509Credentials((c) -> c.addAll(encryption)));
+		List<SigningMethod> signingMethods = signingMethods(idpssoDescriptor);
+		for (SigningMethod method : signingMethods) {
+			builder.assertingPartyDetails(
+					(party) -> party.signingAlgorithms((algorithms) -> algorithms.add(method.getAlgorithm())));
+		}
 		for (SingleSignOnService singleSignOnService : idpssoDescriptor.getSingleSignOnServices()) {
 			Saml2MessageBinding binding;
 			if (singleSignOnService.getBinding().equals(Saml2MessageBinding.POST.getUrn())) {
@@ -127,6 +134,17 @@ class OpenSamlAssertingPartyMetadataConverter {
 		}
 	}
 
+	private List<SigningMethod> signingMethods(IDPSSODescriptor idpssoDescriptor) {
+		Extensions extensions = idpssoDescriptor.getExtensions();
+		List<SigningMethod> result = signingMethods(extensions);
+		if (!result.isEmpty()) {
+			return result;
+		}
+		EntityDescriptor descriptor = (EntityDescriptor) idpssoDescriptor.getParent();
+		extensions = descriptor.getExtensions();
+		return signingMethods(extensions);
+	}
+
 	private EntityDescriptor entityDescriptor(InputStream inputStream) {
 		Document document = document(inputStream);
 		Element element = document.getDocumentElement();
@@ -158,4 +176,11 @@ class OpenSamlAssertingPartyMetadataConverter {
 		}
 	}
 
+	private <T> List<T> signingMethods(Extensions extensions) {
+		if (extensions != null) {
+			return (List<T>) extensions.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME);
+		}
+		return new ArrayList<>();
+	}
+
 }

+ 7 - 2
saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/registration/OpenSamlAssertingPartyMetadataConverterTests.java

@@ -24,6 +24,7 @@ import java.util.Base64;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
 
 import org.springframework.security.saml2.Saml2Exception;
 
@@ -37,7 +38,7 @@ public class OpenSamlAssertingPartyMetadataConverterTests {
 	private static final String ENTITIES_DESCRIPTOR_TEMPLATE = "<md:EntitiesDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\">\n%s</md:EntitiesDescriptor>";
 
 	private static final String ENTITY_DESCRIPTOR_TEMPLATE = "<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\" "
-			+ "entityID=\"entity-id\" "
+			+ "xmlns:alg=\"urn:oasis:names:tc:SAML:metadata:algsupport\" " + "entityID=\"entity-id\" "
 			+ "ID=\"_bf133aac099b99b3d81286e1a341f2d34188043a77fe15bf4bf1487dae9b2ea3\">\n%s"
 			+ "</md:EntityDescriptor>";
 
@@ -49,6 +50,9 @@ public class OpenSamlAssertingPartyMetadataConverterTests {
 			+ "<ds:X509Certificate>" + CERTIFICATE + "</ds:X509Certificate>\n" + "</ds:X509Data>\n" + "</ds:KeyInfo>\n"
 			+ "</md:KeyDescriptor>";
 
+	private static final String EXTENSIONS_TEMPLATE = "<md:Extensions>" + "<alg:SigningMethod Algorithm=\""
+			+ SignatureConstants.ALGO_ID_DIGEST_SHA512 + "\"/>" + "</md:Extensions>";
+
 	private static final String SINGLE_SIGN_ON_SERVICE_TEMPLATE = "<md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" "
 			+ "Location=\"sso-location\"/>";
 
@@ -91,12 +95,13 @@ public class OpenSamlAssertingPartyMetadataConverterTests {
 		String payload = String.format(ENTITY_DESCRIPTOR_TEMPLATE,
 				String.format(IDP_SSO_DESCRIPTOR_TEMPLATE,
 						String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"signing\"")
-								+ String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"encryption\"")
+								+ String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"encryption\"") + EXTENSIONS_TEMPLATE
 								+ String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE)));
 		InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
 		RelyingPartyRegistration registration = this.converter.convert(inputStream).registrationId("one").build();
 		RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
 		assertThat(details.getWantAuthnRequestsSigned()).isFalse();
+		assertThat(details.getSigningAlgorithms()).containsExactly(SignatureConstants.ALGO_ID_DIGEST_SHA512);
 		assertThat(details.getSingleSignOnServiceLocation()).isEqualTo("sso-location");
 		assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.REDIRECT);
 		assertThat(details.getEntityId()).isEqualTo("entity-id");