keycloak-uncached
Changes
adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/Constants.java 2(+2 -0)
adapters/saml/as7-eap6/subsystem/src/main/java/org/keycloak/subsystem/saml/as7/SingleSignOnDefinition.java 7(+6 -1)
adapters/saml/as7-eap6/subsystem/src/main/resources/org/keycloak/subsystem/saml/as7/LocalDescriptions.properties 1(+1 -0)
adapters/saml/as7-eap6/subsystem/src/test/resources/org/keycloak/subsystem/saml/as7/keycloak-saml-1.1.xml 1(+1 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java 1(+1 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java 1(+1 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java 1(+1 -0)
adapters/saml/core/src/main/java/org/keycloak/adapters/saml/profile/AbstractSamlAuthenticationHandler.java 31(+28 -3)
adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/Constants.java 2(+2 -0)
adapters/saml/wildfly/wildfly-subsystem/src/main/java/org/keycloak/subsystem/adapter/saml/extension/SingleSignOnDefinition.java 7(+6 -1)
adapters/saml/wildfly/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/adapter/saml/extension/LocalDescriptions.properties 1(+1 -0)
adapters/saml/wildfly/wildfly-subsystem/src/main/resources/schema/wildfly-keycloak-saml_1_1.xsd 5(+5 -0)
adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1.xml 1(+1 -0)
adapters/saml/wildfly/wildfly-subsystem/src/test/resources/org/keycloak/subsystem/adapter/saml/extension/keycloak-saml-1.1-err.xml 1(+1 -0)
services/src/main/java/org/keycloak/protocol/saml/installation/KeycloakSamlClientInstallation.java 1(+1 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTest.java 18(+18 -0)
testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlAdapterTestStrategy.java 36(+36 -0)
testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keycloak-saml.xml 62(+62 -0)
testsuite/integration/src/test/resources/keycloak-saml/bad-assertion-signed-post/WEB-INF/keystore.jks 0(+0 -0)
testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keycloak-saml.xml 60(+60 -0)
testsuite/integration/src/test/resources/keycloak-saml/missing-assertion-sig/WEB-INF/keystore.jks 0(+0 -0)
testsuite/integration/src/test/resources/keycloak-saml/sales-post-assertion-and-response-sig/WEB-INF/keycloak-saml.xml 60(+60 -0)
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",