keycloak-uncached

Changes

Details

diff --git a/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/Constants.java b/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/Constants.java
index 81c697a..7d30f7f 100755
--- a/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/Constants.java
+++ b/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/Constants.java
@@ -45,6 +45,7 @@ public class Constants {
         static final String KEY_STORE = "KeyStore";
         static final String SIGN_REQUEST = "signRequest";
         static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
+        static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
         static final String REQUEST_BINDING = "requestBinding";
         static final String BINDING_URL = "bindingUrl";
         static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
@@ -97,6 +98,7 @@ public class Constants {
         static final String CERTIFICATE_ALIAS = "alias";
         static final String SIGN_REQUEST = "signRequest";
         static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
+        static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
         static final String REQUEST_BINDING = "requestBinding";
         static final String BINDING_URL = "bindingUrl";
         static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
diff --git a/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/SingleSignOnDefinition.java b/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/SingleSignOnDefinition.java
index 9f7732a..61c55d8 100644
--- a/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/SingleSignOnDefinition.java
+++ b/adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/SingleSignOnDefinition.java
@@ -37,6 +37,11 @@ abstract class SingleSignOnDefinition {
                     .setXmlName(Constants.XML.VALIDATE_RESPONSE_SIGNATURE)
                     .build();
 
+    static final SimpleAttributeDefinition VALIDATE_ASSERTION_SIGNATURE =
+            new SimpleAttributeDefinitionBuilder(Constants.Model.VALIDATE_ASSERTION_SIGNATURE, ModelType.BOOLEAN, true)
+                    .setXmlName(Constants.XML.VALIDATE_ASSERTION_SIGNATURE)
+                    .build();
+
     static final SimpleAttributeDefinition REQUEST_BINDING =
             new SimpleAttributeDefinitionBuilder(Constants.Model.REQUEST_BINDING, ModelType.STRING, true)
                     .setXmlName(Constants.XML.REQUEST_BINDING)
@@ -52,7 +57,7 @@ abstract class SingleSignOnDefinition {
                     .setXmlName(Constants.XML.BINDING_URL)
                     .build();
 
-    static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL};
+    static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, VALIDATE_ASSERTION_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL};
 
     static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
 
diff --git a/adapters/saml/as7-eap6/subsystem/src/main/resources/org/keycloak/subsystem/saml/as7/LocalDescriptions.properties b/adapters/saml/as7-eap6/subsystem/src/main/resources/org/keycloak/subsystem/saml/as7/LocalDescriptions.properties
index 6add1e4..8196235 100755
--- a/adapters/saml/as7-eap6/subsystem/src/main/resources/org/keycloak/subsystem/saml/as7/LocalDescriptions.properties
+++ b/adapters/saml/as7-eap6/subsystem/src/main/resources/org/keycloak/subsystem/saml/as7/LocalDescriptions.properties
@@ -67,6 +67,7 @@ keycloak-saml.IDP.signatureCanonicalizationMethod=Signature canonicalization met
 keycloak-saml.IDP.SingleSignOnService=Single sign-on configuration
 keycloak-saml.IDP.SingleSignOnService.signRequest=Sign SSO requests
 keycloak-saml.IDP.SingleSignOnService.validateResponseSignature=Validate an SSO response signature
+keycloak-saml.IDP.SingleSignOnService.validateAssertionSignature=Validate an SSO assertion signature
 keycloak-saml.IDP.SingleSignOnService.requestBinding=HTTP method to use for requests
 keycloak-saml.IDP.SingleSignOnService.responseBinding=HTTP method to use for responses
 keycloak-saml.IDP.SingleSignOnService.bindingUrl=SSO endpoint URL
diff --git a/adapters/saml/as7-eap6/subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd b/adapters/saml/as7-eap6/subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
index fb893dd..0494a1e 100755
--- a/adapters/saml/as7-eap6/subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
+++ b/adapters/saml/as7-eap6/subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
@@ -132,6 +132,11 @@
                 <xs:documentation>Validate the SSO response signature</xs:documentation>
             </xs:annotation>
         </xs:attribute>
+        <xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional">
+            <xs:annotation>
+                <xs:documentation>Validate the SSO assertion signature</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
         <xs:attribute name="requestBinding" type="xs:string" use="optional">
             <xs:annotation>
                 <xs:documentation>HTTP method to use for requests</xs:documentation>
diff --git a/adapters/saml/as7-eap6/subsystem/src/test/resources/org/keycloak/subsystem/saml/as7/keycloak-saml-1.1.xml b/adapters/saml/as7-eap6/subsystem/src/test/resources/org/keycloak/subsystem/saml/as7/keycloak-saml-1.1.xml
index 31ed630..2380642 100644
--- a/adapters/saml/as7-eap6/subsystem/src/test/resources/org/keycloak/subsystem/saml/as7/keycloak-saml-1.1.xml
+++ b/adapters/saml/as7-eap6/subsystem/src/test/resources/org/keycloak/subsystem/saml/as7/keycloak-saml-1.1.xml
@@ -42,6 +42,7 @@
             <IDP entityID="idp">
                 <SingleSignOnService signRequest="true"
                                      validateResponseSignature="true"
+                                     validateAssertionSignature="true"
                                      requestBinding="POST"
                                      bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
                 <SingleLogoutService
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java
index 73c14a2..7502e5d 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java
@@ -33,6 +33,7 @@ public class IDP implements Serializable {
         private String requestBinding;
         private String responseBinding;
         private String bindingUrl;
+        private boolean validateAssertionSignature;
 
         public boolean isSignRequest() {
             return signRequest;
@@ -50,6 +51,14 @@ public class IDP implements Serializable {
             this.validateResponseSignature = validateResponseSignature;
         }
 
+        public boolean isValidateAssertionSignature() {
+            return validateAssertionSignature;
+        }
+
+        public void setValidateAssertionSignature(boolean validateAssertionSignature) {
+            this.validateAssertionSignature = validateAssertionSignature;
+        }
+
         public String getRequestBinding() {
             return requestBinding;
         }
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java
index 8866203..0085a6a 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java
@@ -68,6 +68,7 @@ public class ConfigXmlConstants {
     public static final String RESPONSE_BINDING_ATTR = "responseBinding";
     public static final String BINDING_URL_ATTR = "bindingUrl";
     public static final String VALIDATE_RESPONSE_SIGNATURE_ATTR = "validateResponseSignature";
+    public static final String VALIDATE_ASSERTION_SIGNATURE_ATTR = "validateAssertionSignature";
     public static final String VALIDATE_REQUEST_SIGNATURE_ATTR = "validateRequestSignature";
     public static final String POST_BINDING_URL_ATTR = "postBindingUrl";
     public static final String REDIRECT_BINDING_URL_ATTR = "redirectBindingUrl";
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
index 356b79b..e5a6ead 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
@@ -149,6 +149,7 @@ public class DeploymentBuilder {
         }
         sso.setSignRequest(sp.getIdp().getSingleSignOnService().isSignRequest());
         sso.setValidateResponseSignature(sp.getIdp().getSingleSignOnService().isValidateResponseSignature());
+        sso.setValidateAssertionSignature(sp.getIdp().getSingleSignOnService().isValidateAssertionSignature());
 
         slo.setSignRequest(sp.getIdp().getSingleLogoutService().isSignRequest());
         slo.setSignResponse(sp.getIdp().getSingleLogoutService().isSignResponse());
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java
index b65f830..e649d1c 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java
@@ -106,6 +106,7 @@ public class IDPXmlParser extends AbstractParser {
         StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader);
         sso.setSignRequest(SPXmlParser.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR, signaturesRequired));
         sso.setValidateResponseSignature(SPXmlParser.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR, signaturesRequired));
+        sso.setValidateAssertionSignature(SPXmlParser.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_ASSERTION_SIGNATURE_ATTR));
         sso.setRequestBinding(SPXmlParser.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR));
         sso.setResponseBinding(SPXmlParser.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR));
         sso.setBindingUrl(SPXmlParser.getAttributeValue(element, ConfigXmlConstants.BINDING_URL_ATTR));
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java
index 4d55f38..9e12f48 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java
@@ -34,6 +34,7 @@ public class DefaultSamlDeployment implements SamlDeployment {
     public static class DefaultSingleSignOnService implements IDP.SingleSignOnService {
         private boolean signRequest;
         private boolean validateResponseSignature;
+        private boolean validateAssertionSignature;
         private Binding requestBinding;
         private Binding responseBinding;
         private String requestBindingUrl;
@@ -49,6 +50,11 @@ public class DefaultSamlDeployment implements SamlDeployment {
         }
 
         @Override
+        public boolean validateAssertionSignature() {
+            return validateAssertionSignature;
+        }
+
+        @Override
         public Binding getRequestBinding() {
             return requestBinding;
         }
@@ -71,6 +77,10 @@ public class DefaultSamlDeployment implements SamlDeployment {
             this.validateResponseSignature = validateResponseSignature;
         }
 
+        public void setValidateAssertionSignature(boolean validateAssertionSignature) {
+            this.validateAssertionSignature = validateAssertionSignature;
+        }
+
         public void setRequestBinding(Binding requestBinding) {
             this.requestBinding = requestBinding;
         }
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
index 1c3766f..e9247b3 100644
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java
@@ -201,7 +201,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
                         return AuthOutcome.FAILED;
                     }
                 }
-                return handleLoginResponse((ResponseType) statusResponse, onCreateSession);
+                return handleLoginResponse((ResponseType) statusResponse, postBinding, onCreateSession);
             } finally {
                 sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
             }
@@ -272,8 +272,7 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
         return false;
     }
 
-    protected AuthOutcome handleLoginResponse(ResponseType responseType, OnSessionCreated onCreateSession) {
-
+    protected AuthOutcome handleLoginResponse(ResponseType responseType, boolean postBinding, OnSessionCreated onCreateSession) {
         AssertionType assertion = null;
         try {
             assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey());
@@ -298,6 +297,32 @@ public abstract class AbstractSamlAuthenticationHandler implements SamlAuthentic
             };
         }
 
+        if (deployment.getIDP().getSingleSignOnService().validateAssertionSignature()) {
+            try {
+                validateSamlSignature(new SAMLDocumentHolder(AssertionUtil.asDocument(assertion)), postBinding, GeneralConstants.SAML_RESPONSE_KEY);
+            } catch (VerificationException e) {
+                log.error("Failed to verify saml assertion signature", e);
+
+                challenge = new AuthChallenge() {
+                    @Override
+                    public boolean challenge(HttpFacade exchange) {
+                        SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.INVALID_SIGNATURE);
+                        exchange.getRequest().setError(error);
+                        exchange.getResponse().sendError(403);
+                        return true;
+                    }
+
+                    @Override
+                    public int getResponseCode() {
+                        return 403;
+                    }
+                };
+                return AuthOutcome.FAILED;
+            } catch (ProcessingException e) {
+                e.printStackTrace();
+            }
+        }
+
         SubjectType subject = assertion.getSubject();
         SubjectType.STSubType subType = subject.getSubType();
         NameIDType subjectNameID = (NameIDType) subType.getBaseID();
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java
index 5f60f34..0b82ff2 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java
@@ -50,6 +50,7 @@ public interface SamlDeployment {
         public interface SingleSignOnService {
             boolean signRequest();
             boolean validateResponseSignature();
+            boolean validateAssertionSignature();
             Binding getRequestBinding();
             Binding getResponseBinding();
             String getRequestBindingUrl();
diff --git a/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd b/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
index 843c865..1ca774b 100755
--- a/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
+++ b/adapters/saml/core/src/main/resources/schema/keycloak_saml_adapter_1_6.xsd
@@ -112,6 +112,7 @@
     <xs:complexType name="sign-on-type">
         <xs:attribute name="signRequest" type="xs:boolean" use="optional"/>
         <xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional"/>
+        <xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional"/>
         <xs:attribute name="requestBinding" type="xs:string" use="optional"/>
         <xs:attribute name="responseBinding" type="xs:string" use="optional"/>
         <xs:attribute name="bindingUrl" type="xs:string" use="optional"/>
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java
index c7d5acc..46bfaed 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java
@@ -45,6 +45,7 @@ public class Constants {
         static final String KEY_STORE = "KeyStore";
         static final String SIGN_REQUEST = "signRequest";
         static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
+        static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
         static final String REQUEST_BINDING = "requestBinding";
         static final String BINDING_URL = "bindingUrl";
         static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
@@ -97,6 +98,7 @@ public class Constants {
         static final String CERTIFICATE_ALIAS = "alias";
         static final String SIGN_REQUEST = "signRequest";
         static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
+        static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
         static final String REQUEST_BINDING = "requestBinding";
         static final String BINDING_URL = "bindingUrl";
         static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/SingleSignOnDefinition.java b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/SingleSignOnDefinition.java
index 8a565a3..d0d95b1 100644
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/SingleSignOnDefinition.java
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/SingleSignOnDefinition.java
@@ -37,6 +37,11 @@ abstract class SingleSignOnDefinition {
                     .setXmlName(Constants.XML.VALIDATE_RESPONSE_SIGNATURE)
                     .build();
 
+    static final SimpleAttributeDefinition VALIDATE_ASSERTION_SIGNATURE =
+            new SimpleAttributeDefinitionBuilder(Constants.Model.VALIDATE_ASSERTION_SIGNATURE, ModelType.BOOLEAN, true)
+                    .setXmlName(Constants.XML.VALIDATE_ASSERTION_SIGNATURE)
+                    .build();
+
     static final SimpleAttributeDefinition REQUEST_BINDING =
             new SimpleAttributeDefinitionBuilder(Constants.Model.REQUEST_BINDING, ModelType.STRING, true)
                     .setXmlName(Constants.XML.REQUEST_BINDING)
@@ -52,7 +57,7 @@ abstract class SingleSignOnDefinition {
                     .setXmlName(Constants.XML.BINDING_URL)
                     .build();
 
-    static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL};
+    static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, VALIDATE_ASSERTION_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL};
 
     static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
 
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties
index 6add1e4..8196235 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties
@@ -67,6 +67,7 @@ keycloak-saml.IDP.signatureCanonicalizationMethod=Signature canonicalization met
 keycloak-saml.IDP.SingleSignOnService=Single sign-on configuration
 keycloak-saml.IDP.SingleSignOnService.signRequest=Sign SSO requests
 keycloak-saml.IDP.SingleSignOnService.validateResponseSignature=Validate an SSO response signature
+keycloak-saml.IDP.SingleSignOnService.validateAssertionSignature=Validate an SSO assertion signature
 keycloak-saml.IDP.SingleSignOnService.requestBinding=HTTP method to use for requests
 keycloak-saml.IDP.SingleSignOnService.responseBinding=HTTP method to use for responses
 keycloak-saml.IDP.SingleSignOnService.bindingUrl=SSO endpoint URL
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
index fb893dd..0494a1e 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd
@@ -132,6 +132,11 @@
                 <xs:documentation>Validate the SSO response signature</xs:documentation>
             </xs:annotation>
         </xs:attribute>
+        <xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional">
+            <xs:annotation>
+                <xs:documentation>Validate the SSO assertion signature</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
         <xs:attribute name="requestBinding" type="xs:string" use="optional">
             <xs:annotation>
                 <xs:documentation>HTTP method to use for requests</xs:documentation>
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml b/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml
index d818308..f703c58 100755
--- a/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml
@@ -44,6 +44,7 @@
             <IDP entityID="idp" signaturesRequired="true" signatureAlgorithm="test" signatureCanonicalizationMethod="test">
                 <SingleSignOnService signRequest="true"
                                      validateResponseSignature="true"
+                                     validateAssertionSignature="true"
                                      requestBinding="POST"
                                      responseBinding="POST"
                                      bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
diff --git a/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1-err.xml b/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1-err.xml
index ed56ccc..5afd0bf 100644
--- a/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1-err.xml
+++ b/adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1-err.xml
@@ -42,6 +42,7 @@
             <IDP entityID="idp" signaturesRequired="true" signatureAlgorithm="test" signatureCanonicalizationMethod="test" encryption="test">
                 <SingleSignOnService signRequest="true"
                                      validateResponseSignature="true"
+                                     validateAssertionSignature="true"
                                      requestBinding="POST"
                                      responseBinding="POST"
                                      bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
index c1b5ef0..bd07882 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
@@ -370,7 +370,8 @@ public class XMLSignatureUtil {
         NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
 
         if (nl == null || nl.getLength() == 0) {
-            throw logger.nullValueError("Cannot find Signature element");
+            logger.debug("Cannot find Signature element");
+            return false;
         }
 
         if (publicKey == null)
diff --git a/services/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java b/services/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java
index ca9de35..4a91db9 100755
--- a/services/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java
@@ -96,6 +96,7 @@ public class KeycloakSamlClientInstallation implements ClientInstallationProvide
         buffer.append(">\n");
         buffer.append("            <SingleSignOnService signRequest=\"").append(Boolean.toString(samlClient.requiresClientSignature())).append("\"\n");
         buffer.append("                                 validateResponseSignature=\"").append(Boolean.toString(samlClient.requiresRealmSignature())).append("\"\n");
+        buffer.append("                                 validateAssertionSignature=\"").append(Boolean.toString(samlClient.requiresAssertionSignature())).append("\"\n");
         buffer.append("                                 requestBinding=\"POST\"\n");
         UriBuilder bindingUrlBuilder = UriBuilder.fromUri(baseUri);
         String bindingUrl = RealmsResource.protocolUrl(bindingUrlBuilder)
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
index 37f2b65..0f692fe 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java
@@ -51,6 +51,7 @@ public class SamlAdapterTest {
             initializeSamlSecuredWar("/keycloak-saml/simple-post2", "/sales-post2",  "post.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/simple-post-passive", "/sales-post-passive", "post-passive.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/signed-post", "/sales-post-sig",  "post-sig.war", classLoader);
+            initializeSamlSecuredWar("/keycloak-saml/sales-post-assertion-and-response-sig", "/sales-post-assertion-and-response-sig",  "sales-post-assertion-and-response-sig.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/signed-post-email", "/sales-post-sig-email",  "post-sig-email.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/signed-post-transient", "/sales-post-sig-transient",  "post-sig-transient.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/signed-post-persistent", "/sales-post-sig-persistent",  "post-sig-persistent.war", classLoader);
@@ -60,6 +61,8 @@ public class SamlAdapterTest {
             initializeSamlSecuredWar("/keycloak-saml/signed-front-get", "/employee-sig-front",  "employee-sig-front.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/bad-client-signed-post", "/bad-client-sales-post-sig",  "bad-client-post-sig.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/bad-realm-signed-post", "/bad-realm-sales-post-sig",  "bad-realm-post-sig.war", classLoader);
+            initializeSamlSecuredWar("/keycloak-saml/bad-assertion-signed-post", "/bad-assertion-sales-post-sig",  "bad-assertion-post-sig.war", classLoader);
+            initializeSamlSecuredWar("/keycloak-saml/missing-assertion-sig", "/missing-assertion-sig",  "missing-assertion-sig.war", classLoader);
             initializeSamlSecuredWar("/keycloak-saml/encrypted-post", "/sales-post-enc",  "post-enc.war", classLoader);
             System.setProperty("app.server.base.url", "http://localhost:8081");
             initializeSamlSecuredWar("/keycloak-saml/simple-input", "/input-portal",  "input.war", classLoader, InputServlet.class, "/secured/*");
@@ -90,6 +93,16 @@ public class SamlAdapterTest {
     }
 
     @Test
+    public void testPostBadAssertionSignature() {
+        testStrategy.testPostBadAssertionSignature();
+    }
+
+    @Test
+    public void testMissingAssertionSignature() {
+        testStrategy.testMissingAssertionSignature();
+    }
+
+    @Test
     public void testPostSimpleUnauthorized() {
         testStrategy.testPostSimpleUnauthorized( new SamlAdapterTestStrategy.CheckAuthError() {
             @Override
@@ -190,6 +203,11 @@ public class SamlAdapterTest {
     }
 
     @Test
+    public void testPostSignedResponseAndAssertionLoginLogout() {
+        testStrategy.testPostSignedResponseAndAssertionLoginLogout();
+    }
+
+    @Test
     public void testIDPDescriptor() throws Exception {
         Client client = ClientBuilder.newClient();
         String text = client.target("http://localhost:8081/auth/realms/master/protocol/saml/descriptor").request().get(String.class);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
index f45255f..6bbfeab 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java
@@ -281,6 +281,16 @@ public class SamlAdapterTestStrategy  extends ExternalResource {
         checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-sig/", true);
 
     }
+    public void testPostSignedResponseAndAssertionLoginLogout() {
+        driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-assertion-and-response-sig/");
+        assertAtLoginPagePostBinding();
+        loginPage.login("bburke", "password");
+        assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/sales-post-assertion-and-response-sig/");
+        Assert.assertTrue(driver.getPageSource().contains("bburke"));
+        driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-assertion-and-response-sig?GLO=true");
+        checkLoggedOut(APP_SERVER_BASE_URL + "/sales-post-assertion-and-response-sig/", true);
+
+    }
     public void testPostSignedLoginLogoutTransientNameID() {
         driver.navigate().to(APP_SERVER_BASE_URL + "/sales-post-sig-transient/");
         assertAtLoginPagePostBinding();
@@ -523,6 +533,32 @@ public class SamlAdapterTestStrategy  extends ExternalResource {
         ErrorServlet.authError = null;
     }
 
+    public void testPostBadAssertionSignature() {
+        ErrorServlet.authError = null;
+        driver.navigate().to(APP_SERVER_BASE_URL + "/bad-assertion-sales-post-sig/");
+        assertAtLoginPagePostBinding();
+        loginPage.login("bburke", "password");
+        assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/bad-assertion-sales-post-sig/saml");
+        System.out.println(driver.getPageSource());
+        Assert.assertNotNull(ErrorServlet.authError);
+        SamlAuthenticationError error = (SamlAuthenticationError)ErrorServlet.authError;
+        Assert.assertEquals(SamlAuthenticationError.Reason.INVALID_SIGNATURE, error.getReason());
+        ErrorServlet.authError = null;
+    }
+
+    public void testMissingAssertionSignature() {
+        ErrorServlet.authError = null;
+        driver.navigate().to(APP_SERVER_BASE_URL + "/missing-assertion-sig/");
+        assertAtLoginPagePostBinding();
+        loginPage.login("bburke", "password");
+        assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/missing-assertion-sig/saml");
+        System.out.println(driver.getPageSource());
+        Assert.assertNotNull(ErrorServlet.authError);
+        SamlAuthenticationError error = (SamlAuthenticationError)ErrorServlet.authError;
+        Assert.assertEquals(SamlAuthenticationError.Reason.INVALID_SIGNATURE, error.getReason());
+        ErrorServlet.authError = null;
+    }
+
     public void testMetadataPostSignedLoginLogout() throws Exception {
 
         driver.navigate().to(APP_SERVER_BASE_URL + "/sales-metadata/");
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000..16f78d9
--- /dev/null
+++ b/testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,62 @@
+<!--
+  ~ Copyright 2016 Red Hat, Inc. and/or its affiliates
+  ~ and other contributors as indicated by the @author tags.
+  ~
+  ~ 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
+  ~
+  ~ http://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.
+  -->
+
+<keycloak-saml-adapter>
+    <SP entityID="http://localhost:8081/bad-assertion-sales-post-sig/"
+        sslPolicy="EXTERNAL"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        logoutPage="/logout.jsp"
+        forceAuthentication="false">
+        <Keys>
+            <Key signing="true" >
+                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                    <PrivateKey alias="http://localhost:8081/bad-realm-sales-post-sig/" password="test123"/>
+                    <Certificate alias="http://localhost:8081/bad-realm-sales-post-sig/"/>
+                </KeyStore>
+            </Key>
+        </Keys>
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp">
+            <SingleSignOnService signRequest="true"
+                                 validateAssertionSignature="true"
+                                 requestBinding="POST"
+                                 bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    />
+
+            <SingleLogoutService
+                    validateRequestSignature="true"
+                    validateResponseSignature="true"
+                    signRequest="true"
+                    signResponse="true"
+                    requestBinding="POST"
+                    responseBinding="POST"
+                    postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    />
+            <Keys>
+                <Key signing="true">
+                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                        <Certificate alias="demo"/>
+                    </KeyStore>
+                </Key>
+            </Keys>
+        </IDP>
+     </SP>
+</keycloak-saml-adapter>
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keystore.jks
new file mode 100755
index 0000000..215384c
Binary files /dev/null and b/testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keystore.jks differ
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000..dc60fda
--- /dev/null
+++ b/testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,60 @@
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2016 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ 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
+  ~
+  ~     http://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.
+  -->
+
+<keycloak-saml-adapter>
+    <SP entityID="http://localhost:8081/missing-assertion-sig/"
+        sslPolicy="EXTERNAL"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        logoutPage="/logout.jsp"
+        forceAuthentication="false">
+        <Keys>
+            <Key signing="true" >
+                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                    <PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/>
+                    <Certificate alias="http://localhost:8080/sales-post-sig/"/>
+                </KeyStore>
+            </Key>
+        </Keys>
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp"
+             signaturesRequired="true">
+        <SingleSignOnService requestBinding="POST"
+                             bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                             validateAssertionSignature="true"
+                             validateResponseSignature="false"
+                    />
+
+            <SingleLogoutService
+                    requestBinding="POST"
+                    responseBinding="POST"
+                    postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    />
+            <Keys>
+                <Key signing="true">
+                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                        <Certificate alias="demo"/>
+                    </KeyStore>
+                </Key>
+            </Keys>
+        </IDP>
+     </SP>
+</keycloak-saml-adapter>
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keystore.jks
new file mode 100755
index 0000000..144830b
Binary files /dev/null and b/testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keystore.jks differ
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keycloak-saml.xml
new file mode 100755
index 0000000..1bd35d1
--- /dev/null
+++ b/testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keycloak-saml.xml
@@ -0,0 +1,60 @@
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2016 Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags.
+  ~
+  ~ 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
+  ~
+  ~     http://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.
+  -->
+
+<keycloak-saml-adapter>
+    <SP entityID="http://localhost:8081/sales-post-assertion-and-response-sig/"
+        sslPolicy="EXTERNAL"
+        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
+        logoutPage="/logout.jsp"
+        forceAuthentication="false">
+        <Keys>
+            <Key signing="true" >
+                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                    <PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/>
+                    <Certificate alias="http://localhost:8080/sales-post-sig/"/>
+                </KeyStore>
+            </Key>
+        </Keys>
+        <PrincipalNameMapping policy="FROM_NAME_ID"/>
+        <RoleIdentifiers>
+            <Attribute name="Role"/>
+        </RoleIdentifiers>
+        <IDP entityID="idp"
+             signaturesRequired="true">
+        <SingleSignOnService requestBinding="POST"
+                             bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                             validateAssertionSignature="true"
+                             validateResponseSignature="true"
+                    />
+
+            <SingleLogoutService
+                    requestBinding="POST"
+                    responseBinding="POST"
+                    postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
+                    />
+            <Keys>
+                <Key signing="true">
+                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
+                        <Certificate alias="demo"/>
+                    </KeyStore>
+                </Key>
+            </Keys>
+        </IDP>
+     </SP>
+</keycloak-saml-adapter>
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keystore.jks
new file mode 100755
index 0000000..144830b
Binary files /dev/null and b/testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keystore.jks differ
diff --git a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
index 92ddf1a..b184a58 100755
--- a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
+++ b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json
@@ -159,6 +159,50 @@
             }
         },
         {
+            "name": "http://localhost:8081/sales-post-assertion-and-response-sig/",
+            "enabled": true,
+            "protocol": "saml",
+            "fullScopeAllowed": true,
+            "baseUrl": "http://localhost:8081/sales-post-assertion-and-response-sig",
+            "redirectUris": [
+                "http://localhost:8081/sales-post-assertion-and-response-sig/*"
+            ],
+            "attributes": {
+                "saml_assertion_consumer_url_post": "http://localhost:8081/sales-post-assertion-and-response-sig/saml",
+                "saml_assertion_consumer_url_redirect": "http://localhost:8081/sales-post-assertion-and-response-sig/saml",
+                "saml_single_logout_service_url_post": "http://localhost:8081/sales-post-assertion-and-response-sig/saml",
+                "saml_single_logout_service_url_redirect": "http://localhost:8081/sales-post-assertion-and-response-sig/saml",
+                "saml.server.signature": "true",
+                "saml.assertion.signature": "true",
+                "saml.signature.algorithm": "RSA_SHA256",
+                "saml.client.signature": "true",
+                "saml.authnstatement": "true",
+                "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+            }
+        },
+        {
+            "name": "http://localhost:8081/missing-assertion-sig/",
+            "enabled": true,
+            "protocol": "saml",
+            "fullScopeAllowed": true,
+            "baseUrl": "http://localhost:8081/missing-assertion-sig",
+            "redirectUris": [
+                "http://localhost:8081/missing-assertion-sig/*"
+            ],
+            "attributes": {
+                "saml_assertion_consumer_url_post": "http://localhost:8081/missing-assertion-sig/saml",
+                "saml_assertion_consumer_url_redirect": "http://localhost:8081/missing-assertion-sig/saml",
+                "saml_single_logout_service_url_post": "http://localhost:8081/missing-assertion-sig/saml",
+                "saml_single_logout_service_url_redirect": "http://localhost:8081/missing-assertion-sig/saml",
+                "saml.server.signature": "true",
+                "saml.assertion.signature": "false",
+                "saml.signature.algorithm": "RSA_SHA256",
+                "saml.client.signature": "true",
+                "saml.authnstatement": "true",
+                "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+            }
+        },
+        {
             "name": "http://localhost:8081/sales-post-sig-transient/",
             "enabled": true,
             "protocol": "saml",
@@ -243,6 +287,23 @@
             }
         },
         {
+            "name": "http://localhost:8081/bad-assertion-sales-post-sig/",
+            "enabled": true,
+            "protocol": "saml",
+            "fullScopeAllowed": true,
+            "baseUrl": "http://localhost:8081/bad-assertion-sales-post-sig/",
+            "adminUrl": "http://localhost:8081/bad-assertion-sales-post-sig/saml",
+            "redirectUris": [
+                "http://localhost:8081/bad-assertion-sales-post-sig/*"
+            ],
+            "attributes": {
+                "saml.assertion.signature": "true",
+                "saml.client.signature": "true",
+                "saml.authnstatement": "true",
+                "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw=="
+            }
+        },
+        {
             "name": "http://localhost:8081/bad-client-sales-post-sig/",
             "enabled": true,
             "protocol": "saml",
@@ -274,6 +335,7 @@
                 "saml_single_logout_service_url_post": "http://localhost:8081/sales-post-enc/saml",
                 "saml_single_logout_service_url_redirect": "http://localhost:8081/sales-post-enc/saml",
                 "saml.server.signature": "true",
+                "saml.assertion.signature": "true",
                 "saml.signature.algorithm": "RSA_SHA512",
                 "saml.client.signature": "true",
                 "saml.encrypt": "true",