mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-26 22:02:41 +00:00
Add support sign SAML metadata
Closes gh-14801
This commit is contained in:
parent
f104d1aeea
commit
801e808f67
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -74,6 +74,8 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
|||||||
|
|
||||||
private boolean usePrettyPrint = true;
|
private boolean usePrettyPrint = true;
|
||||||
|
|
||||||
|
private boolean signMetadata = false;
|
||||||
|
|
||||||
public OpenSamlMetadataResolver() {
|
public OpenSamlMetadataResolver() {
|
||||||
this.entityDescriptorMarshaller = (EntityDescriptorMarshaller) XMLObjectProviderRegistrySupport
|
this.entityDescriptorMarshaller = (EntityDescriptorMarshaller) XMLObjectProviderRegistrySupport
|
||||||
.getMarshallerFactory()
|
.getMarshallerFactory()
|
||||||
@ -111,6 +113,9 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
|||||||
SPSSODescriptor spSsoDescriptor = buildSpSsoDescriptor(registration);
|
SPSSODescriptor spSsoDescriptor = buildSpSsoDescriptor(registration);
|
||||||
entityDescriptor.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME).add(spSsoDescriptor);
|
entityDescriptor.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME).add(spSsoDescriptor);
|
||||||
this.entityDescriptorCustomizer.accept(new EntityDescriptorParameters(entityDescriptor, registration));
|
this.entityDescriptorCustomizer.accept(new EntityDescriptorParameters(entityDescriptor, registration));
|
||||||
|
if (this.signMetadata) {
|
||||||
|
return OpenSamlSigningUtils.sign(entityDescriptor, registration);
|
||||||
|
}
|
||||||
return entityDescriptor;
|
return entityDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +133,7 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
|||||||
/**
|
/**
|
||||||
* Configure whether to pretty-print the metadata XML. This can be helpful when
|
* Configure whether to pretty-print the metadata XML. This can be helpful when
|
||||||
* signing the metadata payload.
|
* signing the metadata payload.
|
||||||
|
*
|
||||||
* @since 6.2
|
* @since 6.2
|
||||||
**/
|
**/
|
||||||
public void setUsePrettyPrint(boolean usePrettyPrint) {
|
public void setUsePrettyPrint(boolean usePrettyPrint) {
|
||||||
@ -238,6 +244,15 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure whether to sign the metadata, defaults to {@code false}.
|
||||||
|
*
|
||||||
|
* @since 6.4
|
||||||
|
*/
|
||||||
|
public void setSignMetadata(boolean signMetadata) {
|
||||||
|
this.signMetadata = signMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A tuple containing an OpenSAML {@link EntityDescriptor} and its associated
|
* A tuple containing an OpenSAML {@link EntityDescriptor} and its associated
|
||||||
* {@link RelyingPartyRegistration}
|
* {@link RelyingPartyRegistration}
|
||||||
|
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2024 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.metadata;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
|
||||||
|
import net.shibboleth.utilities.java.support.xml.SerializeSupport;
|
||||||
|
import org.opensaml.core.xml.XMLObject;
|
||||||
|
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
|
||||||
|
import org.opensaml.core.xml.io.Marshaller;
|
||||||
|
import org.opensaml.core.xml.io.MarshallingException;
|
||||||
|
import org.opensaml.saml.security.impl.SAMLMetadataSignatureSigningParametersResolver;
|
||||||
|
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.SignatureSigningParametersResolver;
|
||||||
|
import org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion;
|
||||||
|
import org.opensaml.xmlsec.crypto.XMLSigningUtil;
|
||||||
|
import org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration;
|
||||||
|
import org.opensaml.xmlsec.keyinfo.KeyInfoGeneratorManager;
|
||||||
|
import org.opensaml.xmlsec.keyinfo.NamedKeyInfoGeneratorManager;
|
||||||
|
import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory;
|
||||||
|
import org.opensaml.xmlsec.signature.SignableXMLObject;
|
||||||
|
import org.opensaml.xmlsec.signature.support.SignatureConstants;
|
||||||
|
import org.opensaml.xmlsec.signature.support.SignatureSupport;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import org.springframework.security.saml2.Saml2Exception;
|
||||||
|
import org.springframework.security.saml2.core.Saml2ParameterNames;
|
||||||
|
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||||
|
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for signing SAML components with OpenSAML
|
||||||
|
*
|
||||||
|
* For internal use only.
|
||||||
|
*
|
||||||
|
* @author Josh Cummings
|
||||||
|
* @since 6.3
|
||||||
|
*/
|
||||||
|
final class OpenSamlSigningUtils {
|
||||||
|
|
||||||
|
static String serialize(XMLObject object) {
|
||||||
|
try {
|
||||||
|
Marshaller marshaller = XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(object);
|
||||||
|
Element element = marshaller.marshall(object);
|
||||||
|
return SerializeSupport.nodeToString(element);
|
||||||
|
}
|
||||||
|
catch (MarshallingException ex) {
|
||||||
|
throw new Saml2Exception(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static <O extends SignableXMLObject> O sign(O object, RelyingPartyRegistration relyingPartyRegistration) {
|
||||||
|
SignatureSigningParameters parameters = resolveSigningParameters(relyingPartyRegistration);
|
||||||
|
try {
|
||||||
|
SignatureSupport.signObject(object, parameters);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new Saml2Exception(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QueryParametersPartial sign(RelyingPartyRegistration registration) {
|
||||||
|
return new QueryParametersPartial(registration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SignatureSigningParameters resolveSigningParameters(
|
||||||
|
RelyingPartyRegistration relyingPartyRegistration) {
|
||||||
|
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||||
|
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningAlgorithms();
|
||||||
|
List<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);
|
||||||
|
String canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
|
||||||
|
SignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();
|
||||||
|
CriteriaSet criteria = new CriteriaSet();
|
||||||
|
BasicSignatureSigningConfiguration signingConfiguration = new BasicSignatureSigningConfiguration();
|
||||||
|
signingConfiguration.setSigningCredentials(credentials);
|
||||||
|
signingConfiguration.setSignatureAlgorithms(algorithms);
|
||||||
|
signingConfiguration.setSignatureReferenceDigestMethods(digests);
|
||||||
|
signingConfiguration.setSignatureCanonicalizationAlgorithm(canonicalization);
|
||||||
|
signingConfiguration.setKeyInfoGeneratorManager(buildSignatureKeyInfoGeneratorManager());
|
||||||
|
criteria.add(new SignatureSigningConfigurationCriterion(signingConfiguration));
|
||||||
|
try {
|
||||||
|
SignatureSigningParameters parameters = resolver.resolveSingle(criteria);
|
||||||
|
Assert.notNull(parameters, "Failed to resolve any signing credential");
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new Saml2Exception(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NamedKeyInfoGeneratorManager buildSignatureKeyInfoGeneratorManager() {
|
||||||
|
final NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager();
|
||||||
|
|
||||||
|
namedManager.setUseDefaultManager(true);
|
||||||
|
final KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager();
|
||||||
|
|
||||||
|
// Generator for X509Credentials
|
||||||
|
final X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();
|
||||||
|
x509Factory.setEmitEntityCertificate(true);
|
||||||
|
x509Factory.setEmitEntityCertificateChain(true);
|
||||||
|
|
||||||
|
defaultManager.registerFactory(x509Factory);
|
||||||
|
|
||||||
|
return namedManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Credential> resolveSigningCredentials(RelyingPartyRegistration relyingPartyRegistration) {
|
||||||
|
List<Credential> credentials = new ArrayList<>();
|
||||||
|
for (Saml2X509Credential x509Credential : relyingPartyRegistration.getSigningX509Credentials()) {
|
||||||
|
X509Certificate certificate = x509Credential.getCertificate();
|
||||||
|
PrivateKey privateKey = x509Credential.getPrivateKey();
|
||||||
|
BasicCredential credential = CredentialSupport.getSimpleCredential(certificate, privateKey);
|
||||||
|
credential.setEntityId(relyingPartyRegistration.getEntityId());
|
||||||
|
credential.setUsageType(UsageType.SIGNING);
|
||||||
|
credentials.add(credential);
|
||||||
|
}
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenSamlSigningUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class QueryParametersPartial {
|
||||||
|
|
||||||
|
final RelyingPartyRegistration registration;
|
||||||
|
|
||||||
|
final Map<String, String> components = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
QueryParametersPartial(RelyingPartyRegistration registration) {
|
||||||
|
this.registration = registration;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryParametersPartial param(String key, String value) {
|
||||||
|
this.components.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameters() {
|
||||||
|
SignatureSigningParameters parameters = resolveSigningParameters(this.registration);
|
||||||
|
Credential credential = parameters.getSigningCredential();
|
||||||
|
String algorithmUri = parameters.getSignatureAlgorithm();
|
||||||
|
this.components.put(Saml2ParameterNames.SIG_ALG, algorithmUri);
|
||||||
|
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||||
|
for (Map.Entry<String, String> component : this.components.entrySet()) {
|
||||||
|
builder.queryParam(component.getKey(),
|
||||||
|
UriUtils.encode(component.getValue(), StandardCharsets.ISO_8859_1));
|
||||||
|
}
|
||||||
|
String queryString = builder.build(true).toString().substring(1);
|
||||||
|
try {
|
||||||
|
byte[] rawSignature = XMLSigningUtil.signWithURI(credential, algorithmUri,
|
||||||
|
queryString.getBytes(StandardCharsets.UTF_8));
|
||||||
|
String b64Signature = Saml2Utils.samlEncode(rawSignature);
|
||||||
|
this.components.put(Saml2ParameterNames.SIGNATURE, b64Signature);
|
||||||
|
}
|
||||||
|
catch (SecurityException ex) {
|
||||||
|
throw new Saml2Exception(ex);
|
||||||
|
}
|
||||||
|
return this.components;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2024 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.metadata;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.zip.Deflater;
|
||||||
|
import java.util.zip.DeflaterOutputStream;
|
||||||
|
import java.util.zip.Inflater;
|
||||||
|
import java.util.zip.InflaterOutputStream;
|
||||||
|
|
||||||
|
import org.springframework.security.saml2.Saml2Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 6.3
|
||||||
|
*/
|
||||||
|
final class Saml2Utils {
|
||||||
|
|
||||||
|
private Saml2Utils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static String samlEncode(byte[] b) {
|
||||||
|
return Base64.getEncoder().encodeToString(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] samlDecode(String s) {
|
||||||
|
return Base64.getMimeDecoder().decode(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] samlDeflate(String s) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||||
|
DeflaterOutputStream deflater = new DeflaterOutputStream(b, new Deflater(Deflater.DEFLATED, true));
|
||||||
|
deflater.write(s.getBytes(StandardCharsets.UTF_8));
|
||||||
|
deflater.finish();
|
||||||
|
return b.toByteArray();
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new Saml2Exception("Unable to deflate string", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String samlInflate(byte[] b) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
InflaterOutputStream iout = new InflaterOutputStream(out, new Inflater(true));
|
||||||
|
iout.write(b);
|
||||||
|
iout.finish();
|
||||||
|
return new String(out.toByteArray(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new Saml2Exception("Unable to inflate string", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -49,6 +49,33 @@ public class OpenSamlMetadataResolverTests {
|
|||||||
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveWhenRelyingPartyAndSignMetadataSetThenMetadataMatches() {
|
||||||
|
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.full()
|
||||||
|
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||||
|
.build();
|
||||||
|
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||||
|
openSamlMetadataResolver.setSignMetadata(true);
|
||||||
|
String metadata = openSamlMetadataResolver.resolve(relyingPartyRegistration);
|
||||||
|
assertThat(metadata).contains("<md:EntityDescriptor")
|
||||||
|
.contains("entityID=\"rp-entity-id\"")
|
||||||
|
.contains("<md:KeyDescriptor use=\"signing\">")
|
||||||
|
.contains("<md:KeyDescriptor use=\"encryption\">")
|
||||||
|
.contains("<ds:X509Certificate>MIICgTCCAeoCCQCuVzyqFgMSyDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBh")
|
||||||
|
.contains("Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\"")
|
||||||
|
.contains("Location=\"https://rp.example.org/acs\" index=\"1\"")
|
||||||
|
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"")
|
||||||
|
.contains("Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"")
|
||||||
|
.contains("CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#")
|
||||||
|
.contains("SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
|
||||||
|
.contains("Reference URI=\"\"")
|
||||||
|
.contains("Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature")
|
||||||
|
.contains("Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"")
|
||||||
|
.contains("DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\"")
|
||||||
|
.contains("DigestValue")
|
||||||
|
.contains("SignatureValue");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolveWhenRelyingPartyNoCredentialsThenMetadataMatches() {
|
public void resolveWhenRelyingPartyNoCredentialsThenMetadataMatches() {
|
||||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials()
|
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials()
|
||||||
@ -122,4 +149,37 @@ public class OpenSamlMetadataResolverTests {
|
|||||||
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveIterableWhenRelyingPartiesAndSignMetadataSetThenMetadataMatches() {
|
||||||
|
RelyingPartyRegistration one = TestRelyingPartyRegistrations.full()
|
||||||
|
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||||
|
.build();
|
||||||
|
RelyingPartyRegistration two = TestRelyingPartyRegistrations.full()
|
||||||
|
.entityId("two")
|
||||||
|
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||||
|
.build();
|
||||||
|
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||||
|
openSamlMetadataResolver.setSignMetadata(true);
|
||||||
|
String metadata = openSamlMetadataResolver.resolve(List.of(one, two));
|
||||||
|
assertThat(metadata).contains("<md:EntitiesDescriptor")
|
||||||
|
.contains("<md:EntityDescriptor")
|
||||||
|
.contains("entityID=\"rp-entity-id\"")
|
||||||
|
.contains("entityID=\"two\"")
|
||||||
|
.contains("<md:KeyDescriptor use=\"signing\">")
|
||||||
|
.contains("<md:KeyDescriptor use=\"encryption\">")
|
||||||
|
.contains("<ds:X509Certificate>MIICgTCCAeoCCQCuVzyqFgMSyDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBh")
|
||||||
|
.contains("Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\"")
|
||||||
|
.contains("Location=\"https://rp.example.org/acs\" index=\"1\"")
|
||||||
|
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"")
|
||||||
|
.contains("Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"")
|
||||||
|
.contains("CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#")
|
||||||
|
.contains("SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
|
||||||
|
.contains("Reference URI=\"\"")
|
||||||
|
.contains("Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature")
|
||||||
|
.contains("Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"")
|
||||||
|
.contains("DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\"")
|
||||||
|
.contains("DigestValue")
|
||||||
|
.contains("SignatureValue");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user