mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Display POST and REDIRECT bindings in the SPSSODescriptor for the SAML IDP provider
Closes #39596 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
309957033e
commit
b4853de5c6
@ -19,7 +19,9 @@ package org.keycloak.saml;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@ -45,9 +47,17 @@ import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.PROTOCOL_
|
||||
public class SPMetadataDescriptor {
|
||||
|
||||
public static EntityDescriptorType buildSPDescriptor(URI loginBinding, URI logoutBinding, URI assertionEndpoint, URI logoutEndpoint,
|
||||
boolean wantAuthnRequestsSigned, boolean wantAssertionsSigned, boolean wantAssertionsEncrypted,
|
||||
String entityId, String nameIDPolicyFormat, List<KeyDescriptorType> signingCerts, List<KeyDescriptorType> encryptionCerts)
|
||||
{
|
||||
boolean wantAuthnRequestsSigned, boolean wantAssertionsSigned, boolean wantAssertionsEncrypted,
|
||||
String entityId, String nameIDPolicyFormat, List<KeyDescriptorType> signingCerts, List<KeyDescriptorType> encryptionCerts) {
|
||||
return buildSPDescriptor(Collections.singletonList(new EndpointType(loginBinding, assertionEndpoint)),
|
||||
Collections.singletonList(new EndpointType(logoutBinding, logoutEndpoint)),
|
||||
wantAuthnRequestsSigned, wantAssertionsSigned, wantAssertionsEncrypted, entityId, nameIDPolicyFormat, signingCerts, encryptionCerts);
|
||||
}
|
||||
|
||||
public static EntityDescriptorType buildSPDescriptor(List<EndpointType> assertionConsumerServices, List<EndpointType> singleLogoutServices,
|
||||
boolean wantAuthnRequestsSigned, boolean wantAssertionsSigned, boolean wantAssertionsEncrypted,
|
||||
String entityId, String nameIDPolicyFormat, List<KeyDescriptorType> signingCerts,
|
||||
List<KeyDescriptorType> encryptionCerts) {
|
||||
EntityDescriptorType entityDescriptor = new EntityDescriptorType(entityId);
|
||||
entityDescriptor.setID(IDGenerator.create("ID_"));
|
||||
|
||||
@ -55,7 +65,7 @@ public class SPMetadataDescriptor {
|
||||
spSSODescriptor.setAuthnRequestsSigned(wantAuthnRequestsSigned);
|
||||
spSSODescriptor.setWantAssertionsSigned(wantAssertionsSigned);
|
||||
spSSODescriptor.addNameIDFormat(nameIDPolicyFormat);
|
||||
spSSODescriptor.addSingleLogoutService(new EndpointType(logoutBinding, logoutEndpoint));
|
||||
singleLogoutServices.forEach(spSSODescriptor::addSingleLogoutService);
|
||||
|
||||
if (wantAuthnRequestsSigned && signingCerts != null) {
|
||||
for (KeyDescriptorType key: signingCerts) {
|
||||
@ -69,10 +79,13 @@ public class SPMetadataDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
IndexedEndpointType assertionConsumerEndpoint = new IndexedEndpointType(loginBinding, assertionEndpoint);
|
||||
assertionConsumerEndpoint.setIsDefault(true);
|
||||
assertionConsumerEndpoint.setIndex(1);
|
||||
spSSODescriptor.addAssertionConsumerService(assertionConsumerEndpoint);
|
||||
for (ListIterator<EndpointType> iter = assertionConsumerServices.listIterator(); iter.hasNext(); ) {
|
||||
EndpointType endpoint = iter.next();
|
||||
IndexedEndpointType assertionConsumerService = new IndexedEndpointType(endpoint.getBinding(), endpoint.getLocation());
|
||||
assertionConsumerService.setIndex(iter.nextIndex());
|
||||
assertionConsumerService.setIsDefault(iter.nextIndex() == 1 ? Boolean.TRUE : null);
|
||||
spSSODescriptor.addAssertionConsumerService(assertionConsumerService);
|
||||
}
|
||||
|
||||
entityDescriptor.addChoiceType(new EntityDescriptorType.EDTChoiceType(Arrays.asList(new EntityDescriptorType.EDTDescriptorChoiceType(spSSODescriptor))));
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
|
||||
import org.keycloak.dom.saml.v2.assertion.NameIDType;
|
||||
import org.keycloak.dom.saml.v2.assertion.SubjectType;
|
||||
import org.keycloak.dom.saml.v2.metadata.AttributeConsumingServiceType;
|
||||
import org.keycloak.dom.saml.v2.metadata.EndpointType;
|
||||
import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
|
||||
import org.keycloak.dom.saml.v2.metadata.KeyDescriptorType;
|
||||
import org.keycloak.dom.saml.v2.metadata.KeyTypes;
|
||||
@ -357,17 +358,6 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
public Response export(UriInfo uriInfo, RealmModel realm, String format) {
|
||||
try
|
||||
{
|
||||
URI authnResponseBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri();
|
||||
|
||||
if (getConfig().isPostBindingAuthnRequest()) {
|
||||
authnResponseBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri();
|
||||
}
|
||||
|
||||
URI logoutBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri();
|
||||
|
||||
if (getConfig().isPostBindingLogout()) {
|
||||
logoutBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri();
|
||||
}
|
||||
URI endpoint = uriInfo.getBaseUriBuilder()
|
||||
.path("realms").path(realm.getName())
|
||||
.path("broker")
|
||||
@ -375,6 +365,20 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
.path("endpoint")
|
||||
.build();
|
||||
|
||||
List<EndpointType> assertionConsumerServices = getConfig().isPostBindingAuthnRequest()
|
||||
? List.of(new EndpointType(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri(), endpoint),
|
||||
new EndpointType(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri(), endpoint),
|
||||
new EndpointType(JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri(), endpoint))
|
||||
: List.of(new EndpointType(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri(), endpoint),
|
||||
new EndpointType(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri(), endpoint),
|
||||
new EndpointType(JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri(), endpoint));
|
||||
|
||||
List<EndpointType> singleLogoutServices = getConfig().isPostBindingLogout()
|
||||
? List.of(new EndpointType(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri(), endpoint),
|
||||
new EndpointType(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri(), endpoint))
|
||||
: List.of(new EndpointType(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri(), endpoint),
|
||||
new EndpointType(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri(), endpoint));
|
||||
|
||||
boolean wantAuthnRequestsSigned = getConfig().isWantAuthnRequestsSigned();
|
||||
boolean wantAssertionsSigned = getConfig().isWantAssertionsSigned();
|
||||
boolean wantAssertionsEncrypted = getConfig().isWantAssertionsEncrypted();
|
||||
@ -419,7 +423,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||
.collect(Collectors.toList());
|
||||
|
||||
EntityDescriptorType entityDescriptor = SPMetadataDescriptor.buildSPDescriptor(
|
||||
authnResponseBinding, logoutBinding, endpoint, endpoint,
|
||||
assertionConsumerServices, singleLogoutServices,
|
||||
wantAuthnRequestsSigned, wantAssertionsSigned, wantAssertionsEncrypted,
|
||||
entityId, nameIDPolicyFormat, signingKeys, encryptionKeys);
|
||||
|
||||
|
||||
@ -104,6 +104,7 @@ import org.keycloak.testsuite.broker.oidc.OverwrittenMappersTestIdentityProvider
|
||||
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
|
||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.KeyUtils;
|
||||
import org.keycloak.testsuite.util.oauth.OAuthClient;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
@ -1190,27 +1191,41 @@ public class IdentityProviderTest extends AbstractAdminTest {
|
||||
Assert.assertEquals("ProtocolSupportEnumeration", expected, actual);
|
||||
|
||||
Assert.assertNotNull("AssertionConsumerService not null", desc.getAssertionConsumerService());
|
||||
Assert.assertEquals("AssertionConsumerService.size", 1, desc.getAssertionConsumerService().size());
|
||||
Assert.assertEquals("AssertionConsumerService.size", 3, desc.getAssertionConsumerService().size());
|
||||
|
||||
IndexedEndpointType endpoint = desc.getAssertionConsumerService().get(0);
|
||||
final URI samlUri = new URI(OAuthClient.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint");
|
||||
|
||||
Assert.assertEquals("AssertionConsumerService.Location",
|
||||
new URI(oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint"), endpoint.getLocation());
|
||||
Assert.assertEquals("AssertionConsumerService.Location", samlUri, endpoint.getLocation());
|
||||
Assert.assertEquals("AssertionConsumerService.Binding",
|
||||
postBindingResponse ? JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri() : JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri(),
|
||||
endpoint.getBinding());
|
||||
Assert.assertTrue("AssertionConsumerService.isDefault", endpoint.isIsDefault());
|
||||
|
||||
endpoint = desc.getAssertionConsumerService().get(1);
|
||||
|
||||
Assert.assertEquals("AssertionConsumerService.Location", samlUri, endpoint.getLocation());
|
||||
Assert.assertEquals("AssertionConsumerService.Binding",
|
||||
postBindingResponse ? JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri() : JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri(),
|
||||
endpoint.getBinding());
|
||||
|
||||
endpoint = desc.getAssertionConsumerService().get(2);
|
||||
|
||||
Assert.assertEquals("AssertionConsumerService.Location", samlUri, endpoint.getLocation());
|
||||
Assert.assertEquals("AssertionConsumerService.Binding", JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri(), endpoint.getBinding());
|
||||
|
||||
Assert.assertNotNull("SingleLogoutService not null", desc.getSingleLogoutService());
|
||||
Assert.assertEquals("SingleLogoutService.size", 1, desc.getSingleLogoutService().size());
|
||||
Assert.assertEquals("SingleLogoutService.size", 2, desc.getSingleLogoutService().size());
|
||||
|
||||
EndpointType sloEndpoint = desc.getSingleLogoutService().get(0);
|
||||
|
||||
Assert.assertEquals("SingleLogoutService.Location",
|
||||
new URI(oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint"), sloEndpoint.getLocation());
|
||||
Assert.assertEquals("SingleLogoutService.Binding",
|
||||
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), sloEndpoint.getBinding());
|
||||
Assert.assertEquals("SingleLogoutService.Location", samlUri, sloEndpoint.getLocation());
|
||||
Assert.assertEquals("SingleLogoutService.Binding", JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri(), sloEndpoint.getBinding());
|
||||
|
||||
sloEndpoint = desc.getSingleLogoutService().get(1);
|
||||
|
||||
Assert.assertEquals("SingleLogoutService.Location", samlUri, sloEndpoint.getLocation());
|
||||
Assert.assertEquals("SingleLogoutService.Binding", JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri(), sloEndpoint.getBinding());
|
||||
|
||||
Assert.assertNotNull("KeyDescriptor not null", desc.getKeyDescriptor());
|
||||
Assert.assertEquals("KeyDescriptor.size", 1, desc.getKeyDescriptor().size());
|
||||
|
||||
@ -396,11 +396,19 @@ public class KcSamlSpDescriptorTest extends AbstractBrokerTest {
|
||||
EntityDescriptorType o = (EntityDescriptorType) parser.parse(new StringInputStream(spDescriptorString));
|
||||
SPSSODescriptorType spDescriptor = o.getChoiceType().get(0).getDescriptors().get(0).getSpDescriptor();
|
||||
|
||||
assertThat(spDescriptor.getSingleLogoutService().size(), is(2));
|
||||
assertThat(spDescriptor.getSingleLogoutService().get(0).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get()));
|
||||
assertThat(spDescriptor.getSingleLogoutService().get(1).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get()));
|
||||
|
||||
assertThat(spDescriptor.getAssertionConsumerService().size(), is(3));
|
||||
assertThat(spDescriptor.getAssertionConsumerService().get(0).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get()));
|
||||
|
||||
assertThat(spDescriptor.getAssertionConsumerService().get(1).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get()));
|
||||
assertThat(spDescriptor.getAssertionConsumerService().get(2).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,11 +427,19 @@ public class KcSamlSpDescriptorTest extends AbstractBrokerTest {
|
||||
EntityDescriptorType o = (EntityDescriptorType) parser.parse(new StringInputStream(spDescriptorString));
|
||||
SPSSODescriptorType spDescriptor = o.getChoiceType().get(0).getDescriptors().get(0).getSpDescriptor();
|
||||
|
||||
assertThat(spDescriptor.getSingleLogoutService().size(), is(2));
|
||||
assertThat(spDescriptor.getSingleLogoutService().get(0).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get()));
|
||||
assertThat(spDescriptor.getSingleLogoutService().get(1).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get()));
|
||||
|
||||
assertThat(spDescriptor.getAssertionConsumerService().size(), is(3));
|
||||
assertThat(spDescriptor.getAssertionConsumerService().get(0).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get()));
|
||||
|
||||
assertThat(spDescriptor.getAssertionConsumerService().get(1).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get()));
|
||||
assertThat(spDescriptor.getAssertionConsumerService().get(2).getBinding().toString(),
|
||||
is(JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,6 +453,8 @@ public class KcSamlSpDescriptorTest extends AbstractBrokerTest {
|
||||
EntityDescriptorType o = (EntityDescriptorType) parser.parse(new StringInputStream(spDescriptorString));
|
||||
SPSSODescriptorType spDescriptor = o.getChoiceType().get(0).getDescriptors().get(0).getSpDescriptor();
|
||||
|
||||
assertThat(spDescriptor.getSingleLogoutService().size(), is(2));
|
||||
assertThat(spDescriptor.getAssertionConsumerService().size(), is(3));
|
||||
assertThat(spDescriptor.getSingleLogoutService().get(0).getBinding().toString(),
|
||||
is(spDescriptor.getAssertionConsumerService().get(0).getBinding().toString()));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user