keycloak-aplcache
Changes
pom.xml 1(+1 -0)
saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java 11(+10 -1)
saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java 11(+10 -1)
services/pom.xml 6(+6 -0)
Details
pom.xml 1(+1 -0)
diff --git a/pom.xml b/pom.xml
index 503b101..68efc36 100755
--- a/pom.xml
+++ b/pom.xml
@@ -80,6 +80,7 @@
<sun.jaxb.version>2.2.11</sun.jaxb.version>
<sun.xsom.version>20140925</sun.xsom.version>
<undertow.version>1.4.11.Final</undertow.version>
+ <woodstox.version>5.0.3</woodstox.version>
<xmlsec.version>2.0.5</xmlsec.version>
<!-- Authorization Drools Policy Provider -->
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
index 867aceb..41461bf 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLAssertionWriter.java
@@ -47,6 +47,7 @@ import java.net.URI;
import java.util.List;
import java.util.Set;
+import javax.xml.crypto.dsig.XMLSignature;
import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ASSERTION_NSURI;
/**
@@ -69,8 +70,17 @@ public class SAMLAssertionWriter extends BaseWriter {
* @throws org.keycloak.saml.common.exceptions.ProcessingException
*/
public void write(AssertionType assertion) throws ProcessingException {
+ write(assertion, false);
+ }
+
+ public void write(AssertionType assertion, boolean forceWriteDsigNamespace) throws ProcessingException {
+ Element sig = assertion.getSignature();
+
StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ASSERTION.get(), ASSERTION_NSURI.get());
StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
+ if (forceWriteDsigNamespace && sig != null && sig.getPrefix() != null && ! sig.hasAttribute("xmlns:" + sig.getPrefix())) {
+ StaxUtil.writeNameSpace(writer, sig.getPrefix(), XMLSignature.XMLNS);
+ }
StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
// Attributes
@@ -82,7 +92,6 @@ public class SAMLAssertionWriter extends BaseWriter {
if (issuer != null)
write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
- Element sig = assertion.getSignature();
if (sig != null)
StaxUtil.writeDOMElement(writer, sig);
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java
index 9327a73..d2a59b9 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/writers/SAMLResponseWriter.java
@@ -38,6 +38,7 @@ import javax.xml.stream.XMLStreamWriter;
import java.net.URI;
import java.util.List;
import org.keycloak.dom.saml.v2.protocol.ExtensionsType;
+import javax.xml.crypto.dsig.XMLSignature;
/**
* Write a SAML Response to stream
@@ -63,8 +64,17 @@ public class SAMLResponseWriter extends BaseWriter {
* @throws org.keycloak.saml.common.exceptions.ProcessingException
*/
public void write(ResponseType response) throws ProcessingException {
+ write(response, false);
+ }
+
+ public void write(ResponseType response, boolean forceWriteDsigNamespace) throws ProcessingException {
+ Element sig = response.getSignature();
+
StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.RESPONSE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
+ if (forceWriteDsigNamespace && sig != null && sig.getPrefix() != null && ! sig.hasAttribute("xmlns:" + sig.getPrefix())) {
+ StaxUtil.writeNameSpace(writer, sig.getPrefix(), XMLSignature.XMLNS);
+ }
StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, JBossSAMLURIConstants.ASSERTION_NSURI.get());
@@ -75,7 +85,6 @@ public class SAMLResponseWriter extends BaseWriter {
write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
}
- Element sig = response.getSignature();
if (sig != null) {
StaxUtil.writeDOMElement(writer, sig);
}
services/pom.xml 6(+6 -0)
diff --git a/services/pom.xml b/services/pom.xml
index b5741f9..733b812 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -145,6 +145,12 @@
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
+ <groupId>com.fasterxml.woodstox</groupId>
+ <artifactId>woodstox-core</artifactId>
+ <version>${woodstox.version}</version> <!-- this version has to match that of used in Wildfly -->
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
</dependency>
diff --git a/services/src/main/java/org/keycloak/broker/saml/SAMLDataMarshaller.java b/services/src/main/java/org/keycloak/broker/saml/SAMLDataMarshaller.java
index 508fcbd..dc32463 100644
--- a/services/src/main/java/org/keycloak/broker/saml/SAMLDataMarshaller.java
+++ b/services/src/main/java/org/keycloak/broker/saml/SAMLDataMarshaller.java
@@ -51,11 +51,11 @@ public class SAMLDataMarshaller extends DefaultDataMarshaller {
if (obj instanceof ResponseType) {
ResponseType responseType = (ResponseType) obj;
SAMLResponseWriter samlWriter = new SAMLResponseWriter(StaxUtil.getXMLStreamWriter(bos));
- samlWriter.write(responseType);
+ samlWriter.write(responseType, true);
} else if (obj instanceof AssertionType) {
AssertionType assertion = (AssertionType) obj;
SAMLAssertionWriter samlWriter = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(bos));
- samlWriter.write(assertion);
+ samlWriter.write(assertion, true);
} else if (obj instanceof AuthnStatementType) {
AuthnStatementType authnStatement = (AuthnStatementType) obj;
SAMLAssertionWriter samlWriter = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(bos));
diff --git a/services/src/test/java/org/keycloak/test/broker/saml/SAMLDataMarshallerTest.java b/services/src/test/java/org/keycloak/test/broker/saml/SAMLDataMarshallerTest.java
index 9a68621..c8647f3 100755
--- a/services/src/test/java/org/keycloak/test/broker/saml/SAMLDataMarshallerTest.java
+++ b/services/src/test/java/org/keycloak/test/broker/saml/SAMLDataMarshallerTest.java
@@ -25,17 +25,22 @@ import org.keycloak.dom.saml.v2.assertion.AssertionType;
import org.keycloak.dom.saml.v2.assertion.AuthnStatementType;
import org.keycloak.dom.saml.v2.assertion.NameIDType;
import org.keycloak.dom.saml.v2.protocol.ResponseType;
+import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
+import java.io.InputStream;
+import org.hamcrest.CoreMatchers;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertThat;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SAMLDataMarshallerTest {
- private static final String TEST_RESPONSE = "<samlp:Response xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_4804cf50-cd96-4b92-823e-89adaa0c78ba\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.920Z\" Destination=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\" InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><samlp:Status><samlp:StatusCode Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\"></samlp:StatusCode></samlp:Status><saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.911Z\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><saml:Subject><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test-user</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><saml:SubjectConfirmationData InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\" NotOnOrAfter=\"2015-11-06T11:05:31.911Z\" Recipient=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore=\"2015-11-06T11:00:31.911Z\" NotOnOrAfter=\"2015-11-06T11:01:31.911Z\"><saml:AudienceRestriction><saml:Audience>http://localhost:8081/auth/realms/realm-with-broker</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name=\"mobile\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">617-666-7777</saml:AttributeValue></saml:Attribute><saml:Attribute Name=\"urn:oid:1.2.840.113549.1.9.1\" FriendlyName=\"email\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">test-user@localhost</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AttributeStatement><saml:Attribute Name=\"Role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">manager</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>";
+ private static final String TEST_RESPONSE = "<samlp:Response xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_4804cf50-cd96-4b92-823e-89adaa0c78ba\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.920Z\" Destination=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\" InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><samlp:Status><samlp:StatusCode Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\"/></samlp:Status><saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.911Z\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><saml:Subject><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test-user</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><saml:SubjectConfirmationData InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\" NotOnOrAfter=\"2015-11-06T11:05:31.911Z\" Recipient=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore=\"2015-11-06T11:00:31.911Z\" NotOnOrAfter=\"2015-11-06T11:01:31.911Z\"><saml:AudienceRestriction><saml:Audience>http://localhost:8081/auth/realms/realm-with-broker</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name=\"mobile\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">617-666-7777</saml:AttributeValue></saml:Attribute><saml:Attribute Name=\"urn:oid:1.2.840.113549.1.9.1\" FriendlyName=\"email\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">test-user@localhost</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AttributeStatement><saml:Attribute Name=\"Role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">manager</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>";
- private static final String TEST_ASSERTION = "<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.911Z\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><saml:Subject><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test-user</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><saml:SubjectConfirmationData InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\" NotOnOrAfter=\"2015-11-06T11:05:31.911Z\" Recipient=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore=\"2015-11-06T11:00:31.911Z\" NotOnOrAfter=\"2015-11-06T11:01:31.911Z\"><saml:AudienceRestriction><saml:Audience>http://localhost:8081/auth/realms/realm-with-broker</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name=\"mobile\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">617-666-7777</saml:AttributeValue></saml:Attribute><saml:Attribute Name=\"urn:oid:1.2.840.113549.1.9.1\" FriendlyName=\"email\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">test-user@localhost</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AttributeStatement><saml:Attribute Name=\"Role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">manager</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion>";
+ private static final String TEST_ASSERTION = "<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.911Z\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><saml:Subject><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test-user</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><saml:SubjectConfirmationData InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\" NotOnOrAfter=\"2015-11-06T11:05:31.911Z\" Recipient=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore=\"2015-11-06T11:00:31.911Z\" NotOnOrAfter=\"2015-11-06T11:01:31.911Z\"><saml:AudienceRestriction><saml:Audience>http://localhost:8081/auth/realms/realm-with-broker</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name=\"mobile\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">617-666-7777</saml:AttributeValue></saml:Attribute><saml:Attribute Name=\"urn:oid:1.2.840.113549.1.9.1\" FriendlyName=\"email\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">test-user@localhost</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AttributeStatement><saml:Attribute Name=\"Role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">manager</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion>";
- private static final String TEST_ASSERTION_WITH_NAME_ID = "<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.911Z\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><saml:Subject><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test-user</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><saml:SubjectConfirmationData InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\" NotOnOrAfter=\"2015-11-06T11:05:31.911Z\" Recipient=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\"></saml:SubjectConfirmationData></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore=\"2015-11-06T11:00:31.911Z\" NotOnOrAfter=\"2015-11-06T11:01:31.911Z\"><saml:AudienceRestriction><saml:Audience>http://localhost:8081/auth/realms/realm-with-broker</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name=\"mobile\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">617-666-7777</saml:AttributeValue></saml:Attribute><saml:Attribute Name=\"urn:oid:1.2.840.113549.1.9.1\" FriendlyName=\"email\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">test-user@localhost</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AttributeStatement><saml:Attribute Name=\"Role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent\">b2c6275838784dba219c92f53ea5493c8ef4da09</saml:NameID></saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion>";
+ private static final String TEST_ASSERTION_WITH_NAME_ID = "<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"ID_29b196c2-d641-45c8-a423-8ed8e54d4cf9\" Version=\"2.0\" IssueInstant=\"2015-11-06T11:00:33.911Z\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">http://localhost:8082/auth/realms/realm-with-saml-idp-basic</saml:Issuer><saml:Subject><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test-user</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"><saml:SubjectConfirmationData InResponseTo=\"ID_c6b90123-f0bb-4c5c-bf9d-388d5bbe467a\" NotOnOrAfter=\"2015-11-06T11:05:31.911Z\" Recipient=\"http://localhost:8081/auth/realms/realm-with-broker/broker/kc-saml-idp-basic/endpoint\"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore=\"2015-11-06T11:00:31.911Z\" NotOnOrAfter=\"2015-11-06T11:01:31.911Z\"><saml:AudienceRestriction><saml:Audience>http://localhost:8081/auth/realms/realm-with-broker</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name=\"mobile\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">617-666-7777</saml:AttributeValue></saml:Attribute><saml:Attribute Name=\"urn:oid:1.2.840.113549.1.9.1\" FriendlyName=\"email\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">test-user@localhost</saml:AttributeValue></saml:Attribute></saml:AttributeStatement><saml:AttributeStatement><saml:Attribute Name=\"Role\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:basic\"><saml:AttributeValue><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent\">b2c6275838784dba219c92f53ea5493c8ef4da09</saml:NameID></saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion>";
private static final String TEST_AUTHN_TYPE = "<saml:AuthnStatement xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\" AuthnInstant=\"2015-11-06T11:00:33.923Z\" SessionIndex=\"fa0f4fd3-8a11-44f4-9acb-ee30c5bb8fe5\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement>";
@@ -95,4 +100,40 @@ public class SAMLDataMarshallerTest {
String serialized = serializer.serialize(authnStatement);
Assert.assertEquals(TEST_AUTHN_TYPE, serialized);
}
+
+ @Test
+ public void testSerializeWithNamespaceInSignatureElement() throws Exception {
+ SAMLParser parser = new SAMLParser();
+ try (InputStream st = SAMLDataMarshallerTest.class.getResourceAsStream("saml-response-ds-ns-in-signature.xml")) {
+ Object parsedObject = parser.parse(st);
+ assertThat(parsedObject, instanceOf(ResponseType.class));
+
+ ResponseType response = (ResponseType) parsedObject;
+
+ SAMLDataMarshaller serializer = new SAMLDataMarshaller();
+ String serialized = serializer.serialize(response.getAssertions().get(0).getAssertion());
+
+ AssertionType deserialized = serializer.deserialize(serialized, AssertionType.class);
+ assertThat(deserialized, CoreMatchers.notNullValue());
+ assertThat(deserialized.getID(), CoreMatchers.is("id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC"));
+ }
+ }
+
+ @Test
+ public void testSerializeWithNamespaceNotInSignatureElement() throws Exception {
+ SAMLParser parser = new SAMLParser();
+ try (InputStream st = SAMLDataMarshallerTest.class.getResourceAsStream("saml-response-ds-ns-above-signature.xml")) {
+ Object parsedObject = parser.parse(st);
+ assertThat(parsedObject, instanceOf(ResponseType.class));
+
+ ResponseType response = (ResponseType) parsedObject;
+
+ SAMLDataMarshaller serializer = new SAMLDataMarshaller();
+ String serialized = serializer.serialize(response.getAssertions().get(0).getAssertion());
+
+ AssertionType deserialized = serializer.deserialize(serialized, AssertionType.class);
+ assertThat(deserialized, CoreMatchers.notNullValue());
+ assertThat(deserialized.getID(), CoreMatchers.is("id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC"));
+ }
+ }
}
diff --git a/services/src/test/resources/org/keycloak/test/broker/saml/saml-response-ds-ns-above-signature.xml b/services/src/test/resources/org/keycloak/test/broker/saml/saml-response-ds-ns-above-signature.xml
new file mode 100644
index 0000000..dfa74aa
--- /dev/null
+++ b/services/src/test/resources/org/keycloak/test/broker/saml/saml-response-ds-ns-above-signature.xml
@@ -0,0 +1,89 @@
+<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
+ xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
+ xmlns:enc="http://www.w3.org/2001/04/xmlenc#"
+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+ xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ Destination="http://SERVER/auth/realms/MY_REALM/broker/saml/endpoint"
+ ID="id-EYgqtumZ-P-Ph7t37f-brUKMwB5MKix0sNjr-0YV"
+ IssueInstant="2017-06-28T03:34:26Z"
+ Version="2.0">
+ <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">SSO</saml:Issuer>
+ <samlp:Status>
+ <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
+ </samlp:Status>
+ <saml:Assertion ID="id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC"
+ IssueInstant="2017-06-28T03:34:26Z"
+ Version="2.0"
+ >
+ <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">SSO</saml:Issuer>
+ <dsig:Signature>
+ <dsig:SignedInfo>
+ <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
+ <dsig:Reference URI="#id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC">
+ <dsig:Transforms>
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
+ <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ </dsig:Transforms>
+ <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+ <dsig:DigestValue>DIGEST</dsig:DigestValue>
+ </dsig:Reference>
+ </dsig:SignedInfo>
+ <dsig:SignatureValue>SIG_VAL</dsig:SignatureValue>
+ </dsig:Signature>
+ <saml:Subject>
+ <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">my_email@my_provider.com</saml:NameID>
+ <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml:SubjectConfirmationData NotOnOrAfter="2017-06-28T03:39:26Z"
+ Recipient="http://SERVER/auth/realms/MY_REALM/broker/saml/endpoint"
+ />
+ </saml:SubjectConfirmation>
+ </saml:Subject>
+ <saml:Conditions NotBefore="2017-06-28T03:34:26Z"
+ NotOnOrAfter="2017-06-28T03:39:26Z"
+ >
+ <saml:AudienceRestriction>
+ <saml:Audience>http://SERVER/auth/realms/MY_REALM</saml:Audience>
+ </saml:AudienceRestriction>
+ </saml:Conditions>
+ <saml:AuthnStatement AuthnInstant="2017-06-28T03:34:26Z"
+ SessionIndex="id-4efQg54WPFyzSEPsepFVZSb8KmeVYtonQNZO1iAE"
+ SessionNotOnOrAfter="2017-06-28T04:34:26Z"
+ >
+ <saml:AuthnContext>
+ <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
+ </saml:AuthnContext>
+ </saml:AuthnStatement>
+ <saml:AttributeStatement>
+ <saml:Attribute Name="lastName"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >Yadav</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute Name="username"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >H183561</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute Name="email"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >my_email@my_provider.com</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute Name="firstName"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >MY_NAME</saml:AttributeValue>
+ </saml:Attribute>
+ </saml:AttributeStatement>
+ </saml:Assertion>
+</samlp:Response>
diff --git a/services/src/test/resources/org/keycloak/test/broker/saml/saml-response-ds-ns-in-signature.xml b/services/src/test/resources/org/keycloak/test/broker/saml/saml-response-ds-ns-in-signature.xml
new file mode 100644
index 0000000..8460b8e
--- /dev/null
+++ b/services/src/test/resources/org/keycloak/test/broker/saml/saml-response-ds-ns-in-signature.xml
@@ -0,0 +1,88 @@
+<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
+ xmlns:enc="http://www.w3.org/2001/04/xmlenc#"
+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+ xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ Destination="http://SERVER/auth/realms/MY_REALM/broker/saml/endpoint"
+ ID="id-EYgqtumZ-P-Ph7t37f-brUKMwB5MKix0sNjr-0YV"
+ IssueInstant="2017-06-28T03:34:26Z"
+ Version="2.0">
+ <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">SSO</saml:Issuer>
+ <samlp:Status>
+ <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
+ </samlp:Status>
+ <saml:Assertion ID="id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC"
+ IssueInstant="2017-06-28T03:34:26Z"
+ Version="2.0"
+ >
+ <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">SSO</saml:Issuer>
+ <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:SignedInfo>
+ <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ <dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
+ <dsig:Reference URI="#id-4r-Xj702KQsM0gJyu3Fqpuwfe-LvDrEcQZpxKrhC">
+ <dsig:Transforms>
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
+ <dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ </dsig:Transforms>
+ <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+ <dsig:DigestValue>DIGEST</dsig:DigestValue>
+ </dsig:Reference>
+ </dsig:SignedInfo>
+ <dsig:SignatureValue>SIG_VAL</dsig:SignatureValue>
+ </dsig:Signature>
+ <saml:Subject>
+ <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">my_email@my_provider.com</saml:NameID>
+ <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+ <saml:SubjectConfirmationData NotOnOrAfter="2017-06-28T03:39:26Z"
+ Recipient="http://SERVER/auth/realms/MY_REALM/broker/saml/endpoint"
+ />
+ </saml:SubjectConfirmation>
+ </saml:Subject>
+ <saml:Conditions NotBefore="2017-06-28T03:34:26Z"
+ NotOnOrAfter="2017-06-28T03:39:26Z"
+ >
+ <saml:AudienceRestriction>
+ <saml:Audience>http://SERVER/auth/realms/MY_REALM</saml:Audience>
+ </saml:AudienceRestriction>
+ </saml:Conditions>
+ <saml:AuthnStatement AuthnInstant="2017-06-28T03:34:26Z"
+ SessionIndex="id-4efQg54WPFyzSEPsepFVZSb8KmeVYtonQNZO1iAE"
+ SessionNotOnOrAfter="2017-06-28T04:34:26Z"
+ >
+ <saml:AuthnContext>
+ <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
+ </saml:AuthnContext>
+ </saml:AuthnStatement>
+ <saml:AttributeStatement>
+ <saml:Attribute Name="lastName"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >Yadav</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute Name="username"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >H183561</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute Name="email"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >my_email@my_provider.com</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute Name="firstName"
+ NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
+ >
+ <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xsi:type="xs:string"
+ >MY_NAME</saml:AttributeValue>
+ </saml:Attribute>
+ </saml:AttributeStatement>
+ </saml:Assertion>
+</samlp:Response>