keycloak-aplcache

Details

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 1cd28fd..4adeddf 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,74 +73,78 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
             List<EntityDescriptorType.EDTChoiceType> choiceType = entityType.getChoiceType();
 
             if (!choiceType.isEmpty()) {
-                EntityDescriptorType.EDTChoiceType edtChoiceType = choiceType.get(0);
-                List<EntityDescriptorType.EDTDescriptorChoiceType> descriptors = edtChoiceType.getDescriptors();
-
-                if (!descriptors.isEmpty()) {
-                    EntityDescriptorType.EDTDescriptorChoiceType edtDescriptorChoiceType = descriptors.get(0);
-                    IDPSSODescriptorType idpDescriptor = edtDescriptorChoiceType.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;
-                            }
+                IDPSSODescriptorType idpDescriptor = null;
+
+                //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<EntityDescriptorType.EDTDescriptorChoiceType> descriptors = edtChoiceType.getDescriptors();
 
+                    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();
                         }
-                        samlIdentityProviderConfig.setSingleLogoutServiceUrl(singleLogoutServiceUrl);
-                        samlIdentityProviderConfig.setSingleSignOnServiceUrl(singleSignOnServiceUrl);
-                        samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned());
-                        samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned());
-                        samlIdentityProviderConfig.setPostBindingResponse(postBinding);
-                        samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding);
-
-                        List<KeyDescriptorType> 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();
-                                }
-                            }
+                    }
+                    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;
                         }
 
-                        if (defaultCertificate != null) {
-                            if (samlIdentityProviderConfig.getSigningCertificate() == null) {
-                                samlIdentityProviderConfig.setSigningCertificate(defaultCertificate);
+                    }
+                    samlIdentityProviderConfig.setSingleLogoutServiceUrl(singleLogoutServiceUrl);
+                    samlIdentityProviderConfig.setSingleSignOnServiceUrl(singleSignOnServiceUrl);
+                    samlIdentityProviderConfig.setWantAuthnRequestsSigned(idpDescriptor.isWantAuthnRequestsSigned());
+                    samlIdentityProviderConfig.setValidateSignature(idpDescriptor.isWantAuthnRequestsSigned());
+                    samlIdentityProviderConfig.setPostBindingResponse(postBinding);
+                    samlIdentityProviderConfig.setPostBindingAuthnRequest(postBinding);
+
+                    List<KeyDescriptorType> 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 (samlIdentityProviderConfig.getEncryptionPublicKey() == null) {
-                                samlIdentityProviderConfig.setEncryptionPublicKey(defaultCertificate);
-                            }
+                    if (defaultCertificate != null) {
+                        if (samlIdentityProviderConfig.getSigningCertificate() == null) {
+                            samlIdentityProviderConfig.setSigningCertificate(defaultCertificate);
                         }
 
-                        return samlIdentityProviderConfig.getConfig();
+                        if (samlIdentityProviderConfig.getEncryptionPublicKey() == null) {
+                            samlIdentityProviderConfig.setEncryptionPublicKey(defaultCertificate);
+                        }
                     }
+
+                    return samlIdentityProviderConfig.getConfig();
                 }
             }
         } catch (ParsingException pe) {
diff --git a/distribution/server-overlay/eap6/eap6-server-overlay/assembly.xml b/distribution/server-overlay/eap6/eap6-server-overlay/assembly.xml
index 9a9e490..83ee9e3 100755
--- a/distribution/server-overlay/eap6/eap6-server-overlay/assembly.xml
+++ b/distribution/server-overlay/eap6/eap6-server-overlay/assembly.xml
@@ -14,7 +14,7 @@
             <outputDirectory>modules/system/layers/base</outputDirectory>
         </fileSet>
         <fileSet>
-            <directory>../../../forms/common-themes/src/main/resources/theme</directory>
+            <directory>../../../../forms/common-themes/src/main/resources/theme</directory>
             <outputDirectory>standalone/configuration/themes</outputDirectory>
             <includes>
                 <include>**/**</include>
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder.java
index d2f3545..c1a1a68 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder.java
@@ -367,7 +367,7 @@ public class SAML2BindingBuilder<T extends SAML2BindingBuilder> {
         }
 
         if (sign) {
-            builder.queryParam(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, signatureAlgorithm.getJavaSignatureAlgorithm());
+            builder.queryParam(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, signatureAlgorithm.getXmlSignatureMethod());
             URI uri = builder.build();
             String rawQuery = uri.getRawQuery();
             Signature signature = signatureAlgorithm.createSignature();
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder2.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder2.java
index c377206..b86452d 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder2.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2BindingBuilder2.java
@@ -120,11 +120,12 @@ public class SAML2BindingBuilder2<T extends SAML2BindingBuilder2> {
         protected Document document;
 
         public PostBindingBuilder(Document document) throws ProcessingException {
-            if (encrypt) encryptDocument(document);
             this.document = document;
             if (signAssertions) {
                 signAssertion(document);
             }
+            //Per SAML spec 6.2 Encrypting assertions must happen after the assertions are signed
+            if (encrypt) encryptDocument(document);
             if (sign) {
                 signDocument(document);
             }
@@ -151,11 +152,12 @@ public class SAML2BindingBuilder2<T extends SAML2BindingBuilder2> {
         protected Document document;
 
         public RedirectBindingBuilder(Document document) throws ProcessingException {
-            if (encrypt) encryptDocument(document);
             this.document = document;
             if (signAssertions) {
                 signAssertion(document);
             }
+            //Per SAML spec 6.2 Encrypting assertions must happen after the assertions are signed
+            if (encrypt) encryptDocument(document);
         }
 
         public Document getDocument() {
@@ -340,7 +342,7 @@ public class SAML2BindingBuilder2<T extends SAML2BindingBuilder2> {
         }
 
         if (sign) {
-            builder.queryParam(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, signatureAlgorithm.getJavaSignatureAlgorithm());
+            builder.queryParam(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, signatureAlgorithm.getXmlSignatureMethod());
             URI uri = builder.build();
             String rawQuery = uri.getRawQuery();
             Signature signature = signatureAlgorithm.createSignature();
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index e4e8f6e..54dff3a 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -448,8 +448,12 @@ public class SamlProtocol implements LoginProtocol {
         if (roleListMapper == null) return;
         AssertionType assertion = response.getAssertions().get(0).getAssertion();
         AttributeStatementType attributeStatement = new AttributeStatementType();
-        assertion.addStatement(attributeStatement);
         roleListMapper.mapper.mapRoles(attributeStatement, roleListMapper.model, session, userSession, clientSession);
+
+        //SAML Spec 2.7.3 AttributeStatement must contain one or more Attribute or EncryptedAttribute
+        if(attributeStatement.getAttributes().size() > 0) {
+            assertion.addStatement(attributeStatement);
+        }
     }
 
 
diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index f95d7d8..9bbfcf5 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -64,11 +64,7 @@ import org.keycloak.services.validation.Validation;
 import org.keycloak.social.SocialIdentityProvider;
 import org.keycloak.util.ObjectUtil;
 
-import javax.ws.rs.GET;
-import javax.ws.rs.OPTIONS;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.QueryParam;
+import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
@@ -130,6 +126,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
         this.event = new EventBuilder(realmModel, session, clientConnection).event(EventType.IDENTITY_PROVIDER_LOGIN);
     }
 
+    @POST
+    @Path("/{provider_id}/login")
+    public Response performPostLogin(@PathParam("provider_id") String providerId, @QueryParam("code") String code) {
+        return performLogin(providerId, code);
+    }
+
     @GET
     @Path("/{provider_id}/login")
     public Response performLogin(@PathParam("provider_id") String providerId, @QueryParam("code") String code) {