From 80f91b5fa55b6c17cc918595d13d185b70e5e3c8 Mon Sep 17 00:00:00 2001 From: Dane Barentine Date: Mon, 14 Sep 2015 14:09:57 -0700 Subject: [PATCH] KEYCLOAK-1848 Fix consuming of metadata when EntityDescriptor includes multiple Descriptors --- .../saml/SAMLIdentityProviderFactory.java | 134 +++++++++--------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java index 1cd28fd6af..4adeddfd29 100755 --- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java +++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java @@ -73,75 +73,79 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory List choiceType = entityType.getChoiceType(); if (!choiceType.isEmpty()) { - EntityDescriptorType.EDTChoiceType edtChoiceType = choiceType.get(0); - List descriptors = edtChoiceType.getDescriptors(); + IDPSSODescriptorType idpDescriptor = null; - if (!descriptors.isEmpty()) { - EntityDescriptorType.EDTDescriptorChoiceType edtDescriptorChoiceType = descriptors.get(0); - IDPSSODescriptorType idpDescriptor = edtDescriptorChoiceType.getIdpDescriptor(); + //Metadata documents can contain multiple Descriptors (See ADFS metadata documents) such as RoleDescriptor, SPSSODescriptor, IDPSSODescriptor. + //So we need to loop through to find the IDPSSODescriptor. + for(EntityDescriptorType.EDTChoiceType edtChoiceType : entityType.getChoiceType()) { + List descriptors = edtChoiceType.getDescriptors(); - if (idpDescriptor != null) { - SAMLIdentityProviderConfig samlIdentityProviderConfig = new SAMLIdentityProviderConfig(); - String singleSignOnServiceUrl = null; - boolean postBinding = false; - for (EndpointType endpoint : idpDescriptor.getSingleSignOnService()) { - if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) { - singleSignOnServiceUrl = endpoint.getLocation().toString(); - postBinding = true; - break; - } else if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){ - singleSignOnServiceUrl = endpoint.getLocation().toString(); - } - } - String singleLogoutServiceUrl = null; - for (EndpointType endpoint : idpDescriptor.getSingleLogoutService()) { - if (postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) { - singleLogoutServiceUrl = endpoint.getLocation().toString(); - break; - } else if (!postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){ - singleLogoutServiceUrl = endpoint.getLocation().toString(); - break; - } - - } - samlIdentityProviderConfig.setSingleLogoutServiceUrl(singleLogoutServiceUrl); - samlIdentityProviderConfig.setSingleSignOnServiceUrl(singleSignOnServiceUrl); - samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned()); - samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned()); - samlIdentityProviderConfig.setPostBindingResponse(postBinding); - samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding); - - List keyDescriptor = idpDescriptor.getKeyDescriptor(); - String defaultCertificate = null; - - if (keyDescriptor != null) { - for (KeyDescriptorType keyDescriptorType : keyDescriptor) { - Element keyInfo = keyDescriptorType.getKeyInfo(); - Element x509KeyInfo = DocumentUtil.getChildElement(keyInfo, new QName("dsig", "X509Certificate")); - - if (KeyTypes.SIGNING.equals(keyDescriptorType.getUse())) { - samlIdentityProviderConfig.setSigningCertificate(x509KeyInfo.getTextContent()); - } else if (KeyTypes.ENCRYPTION.equals(keyDescriptorType.getUse())) { - samlIdentityProviderConfig.setEncryptionPublicKey(x509KeyInfo.getTextContent()); - } else if (keyDescriptorType.getUse() == null) { - defaultCertificate = x509KeyInfo.getTextContent(); - } - } - } - - if (defaultCertificate != null) { - if (samlIdentityProviderConfig.getSigningCertificate() == null) { - samlIdentityProviderConfig.setSigningCertificate(defaultCertificate); - } - - if (samlIdentityProviderConfig.getEncryptionPublicKey() == null) { - samlIdentityProviderConfig.setEncryptionPublicKey(defaultCertificate); - } - } - - return samlIdentityProviderConfig.getConfig(); + if(!descriptors.isEmpty() && descriptors.get(0).getIdpDescriptor() != null) { + idpDescriptor = descriptors.get(0).getIdpDescriptor(); } } + + if (idpDescriptor != null) { + SAMLIdentityProviderConfig samlIdentityProviderConfig = new SAMLIdentityProviderConfig(); + String singleSignOnServiceUrl = null; + boolean postBinding = false; + for (EndpointType endpoint : idpDescriptor.getSingleSignOnService()) { + if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) { + singleSignOnServiceUrl = endpoint.getLocation().toString(); + postBinding = true; + break; + } else if (endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){ + singleSignOnServiceUrl = endpoint.getLocation().toString(); + } + } + String singleLogoutServiceUrl = null; + for (EndpointType endpoint : idpDescriptor.getSingleLogoutService()) { + if (postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get())) { + singleLogoutServiceUrl = endpoint.getLocation().toString(); + break; + } else if (!postBinding && endpoint.getBinding().toString().equals(JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get())){ + singleLogoutServiceUrl = endpoint.getLocation().toString(); + break; + } + + } + samlIdentityProviderConfig.setSingleLogoutServiceUrl(singleLogoutServiceUrl); + samlIdentityProviderConfig.setSingleSignOnServiceUrl(singleSignOnServiceUrl); + samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned()); + samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned()); + samlIdentityProviderConfig.setPostBindingResponse(postBinding); + samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding); + + List keyDescriptor = idpDescriptor.getKeyDescriptor(); + String defaultCertificate = null; + + if (keyDescriptor != null) { + for (KeyDescriptorType keyDescriptorType : keyDescriptor) { + Element keyInfo = keyDescriptorType.getKeyInfo(); + Element x509KeyInfo = DocumentUtil.getChildElement(keyInfo, new QName("dsig", "X509Certificate")); + + if (KeyTypes.SIGNING.equals(keyDescriptorType.getUse())) { + samlIdentityProviderConfig.setSigningCertificate(x509KeyInfo.getTextContent()); + } else if (KeyTypes.ENCRYPTION.equals(keyDescriptorType.getUse())) { + samlIdentityProviderConfig.setEncryptionPublicKey(x509KeyInfo.getTextContent()); + } else if (keyDescriptorType.getUse() == null) { + defaultCertificate = x509KeyInfo.getTextContent(); + } + } + } + + if (defaultCertificate != null) { + if (samlIdentityProviderConfig.getSigningCertificate() == null) { + samlIdentityProviderConfig.setSigningCertificate(defaultCertificate); + } + + if (samlIdentityProviderConfig.getEncryptionPublicKey() == null) { + samlIdentityProviderConfig.setEncryptionPublicKey(defaultCertificate); + } + } + + return samlIdentityProviderConfig.getConfig(); + } } } catch (ParsingException pe) { throw new RuntimeException("Could not parse IdP SAML Metadata", pe);