Merge pull request #4499 from pskopek/anyTypeAttribute
[KEYCLOAK-4374] Support SAML 2.0 AttributeValue of type anyType and nil in Assertions
This commit is contained in:
commit
d3c30c30d4
6 changed files with 348 additions and 17 deletions
|
@ -49,10 +49,13 @@ import org.w3c.dom.Element;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
import javax.xml.stream.XMLEventWriter;
|
||||||
|
import javax.xml.stream.XMLOutputFactory;
|
||||||
import javax.xml.stream.events.Attribute;
|
import javax.xml.stream.events.Attribute;
|
||||||
import javax.xml.stream.events.EndElement;
|
import javax.xml.stream.events.EndElement;
|
||||||
import javax.xml.stream.events.StartElement;
|
import javax.xml.stream.events.StartElement;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -294,7 +297,22 @@ public class SAMLParserUtil {
|
||||||
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
StaxParserUtil.validate(startElement, JBossSAMLConstants.ATTRIBUTE_VALUE.get());
|
StaxParserUtil.validate(startElement, JBossSAMLConstants.ATTRIBUTE_VALUE.get());
|
||||||
|
|
||||||
Attribute type = startElement.getAttributeByName(new QName(JBossSAMLURIConstants.XSI_NSURI.get(), "type", "xsi"));
|
Attribute type = startElement.getAttributeByName(new QName(JBossSAMLURIConstants.XSI_NSURI.get(), JBossSAMLConstants.TYPE.get(), JBossSAMLURIConstants.XSI_PREFIX.get()));
|
||||||
|
Attribute nil = startElement.getAttributeByName(new QName(JBossSAMLURIConstants.XSI_NSURI.get(), "nil", JBossSAMLURIConstants.XSI_PREFIX.get()));
|
||||||
|
if (nil != null) {
|
||||||
|
String nilValue = StaxParserUtil.getAttributeValue(nil);
|
||||||
|
if (nilValue != null
|
||||||
|
&& (nilValue.equalsIgnoreCase("true") || nilValue.equals("1"))) {
|
||||||
|
String elementText = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
|
if (elementText == null || elementText.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
throw logger.nullValueError("nil attribute is not in SAML20 format");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw logger.parserRequiredAttribute(JBossSAMLURIConstants.XSI_PREFIX.get() + ":nil");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
if (StaxParserUtil.hasTextAhead(xmlEventReader)) {
|
if (StaxParserUtil.hasTextAhead(xmlEventReader)) {
|
||||||
return StaxParserUtil.getElementText(xmlEventReader);
|
return StaxParserUtil.getElementText(xmlEventReader);
|
||||||
|
@ -316,25 +334,54 @@ public class SAMLParserUtil {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw logger.unsupportedType(StaxParserUtil.getStartElementName(startElement));
|
// when no type attribute assigned -> assume anyType
|
||||||
|
return parseAnyTypeAsString(xmlEventReader);
|
||||||
}
|
}
|
||||||
// RK Added an additional type check for base64Binary type as calheers is passing this type
|
// RK Added an additional type check for base64Binary type as calheers is passing this type
|
||||||
String typeValue = StaxParserUtil.getAttributeValue(type);
|
String typeValue = StaxParserUtil.getAttributeValue(type);
|
||||||
if (typeValue.contains(":string")) {
|
if (typeValue.contains(":string")) {
|
||||||
return StaxParserUtil.getElementText(xmlEventReader);
|
return StaxParserUtil.getElementText(xmlEventReader);
|
||||||
} else if (typeValue.contains(":anyType")) {
|
} else if (typeValue.contains(":anyType")) {
|
||||||
// TODO: for now assume that it is a text value that can be parsed and set as the attribute value
|
return parseAnyTypeAsString(xmlEventReader);
|
||||||
return StaxParserUtil.getElementText(xmlEventReader);
|
|
||||||
} else if(typeValue.contains(":base64Binary")){
|
} else if(typeValue.contains(":base64Binary")){
|
||||||
return StaxParserUtil.getElementText(xmlEventReader);
|
return StaxParserUtil.getElementText(xmlEventReader);
|
||||||
} else if(typeValue.contains(":boolean")){
|
} else if(typeValue.contains(":boolean")){
|
||||||
return StaxParserUtil.getElementText(xmlEventReader);
|
return StaxParserUtil.getElementText(xmlEventReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
throw logger.parserUnknownXSI(typeValue);
|
throw logger.parserUnknownXSI(typeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String parseAnyTypeAsString(XMLEventReader xmlEventReader) throws ParsingException {
|
||||||
|
try {
|
||||||
|
XMLEvent event = xmlEventReader.peek();
|
||||||
|
if (event.isStartElement()) {
|
||||||
|
event = xmlEventReader.nextTag();
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(sw);
|
||||||
|
//QName tagName = event.asStartElement().getName();
|
||||||
|
int tagLevel = 1;
|
||||||
|
do {
|
||||||
|
writer.add(event);
|
||||||
|
event = (XMLEvent) xmlEventReader.next();
|
||||||
|
if (event.isStartElement()) {
|
||||||
|
tagLevel++;
|
||||||
|
}
|
||||||
|
if (event.isEndElement()) {
|
||||||
|
tagLevel--;
|
||||||
|
}
|
||||||
|
} while (xmlEventReader.hasNext() && tagLevel > 0);
|
||||||
|
writer.add(event);
|
||||||
|
writer.flush();
|
||||||
|
return sw.toString();
|
||||||
|
} else {
|
||||||
|
return StaxParserUtil.getElementText(xmlEventReader);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw logger.parserError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the AuthnStatement inside the assertion
|
* Parse the AuthnStatement inside the assertion
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,25 +16,34 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.saml.processing.core.parsers.saml;
|
package org.keycloak.saml.processing.core.parsers.saml;
|
||||||
|
|
||||||
import org.keycloak.common.util.Base64;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import org.keycloak.common.util.DerUtils;
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import org.keycloak.dom.saml.v2.assertion.NameIDType;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.common.util.Base64;
|
||||||
import static org.junit.Assert.*;
|
import org.keycloak.common.util.DerUtils;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.AttributeType;
|
||||||
|
import org.keycloak.dom.saml.v2.assertion.NameIDType;
|
||||||
|
import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
|
||||||
import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
|
import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
|
||||||
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||||
|
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||||
import org.junit.Before;
|
import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -216,4 +225,106 @@ public class SAMLParserTest {
|
||||||
assertThat(parsedObject, instanceOf(ResponseType.class));
|
assertThat(parsedObject, instanceOf(ResponseType.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaml20AssertionsAnyTypeAttributeValue() throws Exception {
|
||||||
|
|
||||||
|
String[] xmlSamples = {
|
||||||
|
"saml20-assertion-anytype-attribute-value.xml",
|
||||||
|
"saml20-assertion-example.xml"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String fileName: xmlSamples) {
|
||||||
|
try (InputStream st = SAMLParserTest.class.getResourceAsStream(fileName)) {
|
||||||
|
Object parsedObject = parser.parse(st);
|
||||||
|
assertThat("Problem detected in " + fileName + " sample.", parsedObject, instanceOf(AssertionType.class));
|
||||||
|
checkCheckParsedResult(fileName, (AssertionType)parsedObject);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("Problem detected in " + fileName + " sample.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCheckParsedResult(String fileName, AssertionType assertion) throws Exception {
|
||||||
|
AttributeStatementType attributeStatementType = assertion.getAttributeStatements().iterator().next();
|
||||||
|
if ("saml20-assertion-anytype-attribute-value.xml".equals(fileName)) {
|
||||||
|
assertTrue("There has to be 3 attributes", attributeStatementType.getAttributes().size() == 3);
|
||||||
|
for (AttributeStatementType.ASTChoiceType choiceType: attributeStatementType.getAttributes()) {
|
||||||
|
AttributeType attr = choiceType.getAttribute();
|
||||||
|
String attrName = attr.getName();
|
||||||
|
String attrValueStatement = "unexpected value of attribute " + attrName + " of " + fileName;
|
||||||
|
String attrTypeStatement = "unexpected type of attribute " + attrName + " of " + fileName;
|
||||||
|
// test selected attributes
|
||||||
|
if (attrName.equals("attr:type:string")) {
|
||||||
|
assertEquals(attrValueStatement, attr.getAttributeValue().get(0), "CITIZEN");
|
||||||
|
} else if (attrName.equals("attr:notype:string")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertEquals(attrValueStatement, value, "CITIZEN");
|
||||||
|
} else if (attrName.equals("attr:notype:element")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertThat(attrValueStatement, value, containsString("hospitaal x"));
|
||||||
|
value = (String)attr.getAttributeValue().get(1);
|
||||||
|
assertThat(attrValueStatement, value, containsString("hopital x"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("saml20-assertion-example.xml".equals(fileName)) {
|
||||||
|
assertThat("There has to be 9 attributes", attributeStatementType.getAttributes().size(), is(9));
|
||||||
|
for (AttributeStatementType.ASTChoiceType choiceType: attributeStatementType.getAttributes()) {
|
||||||
|
AttributeType attr = choiceType.getAttribute();
|
||||||
|
String attrName = attr.getName();
|
||||||
|
String attrValueStatement = "unexpected value of attribute " + attrName + " of " + fileName;
|
||||||
|
String attrTypeStatement = "unexpected type of attribute " + attrName + " of " + fileName;
|
||||||
|
// test selected attributes
|
||||||
|
if (attrName.equals("portal_id")) {
|
||||||
|
assertEquals(attrValueStatement, attr.getAttributeValue().get(0), "060D00000000SHZ");
|
||||||
|
} else if (attrName.equals("organization_id")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertThat(attrValueStatement, value, containsString("<n3:stuff xmlns:n3=\"ftp://example.org\">00DD0000000F7L5</n3:stuff>"));
|
||||||
|
} else if (attrName.equals("has_sub_organization")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertThat(attrValueStatement, value, containsString("true"));
|
||||||
|
} else if (attrName.equals("anytype_test")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertThat(attrValueStatement, value, containsString("<elem2>val2</elem2>"));
|
||||||
|
} else if (attrName.equals("anytype_no_xml_test")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertEquals(attrValueStatement, value, "value_no_xml");
|
||||||
|
} else if (attrName.equals("logouturl")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertEquals(attrValueStatement, value, "http://www.salesforce.com/security/del_auth/SsoLogoutPage.html");
|
||||||
|
} else if (attrName.equals("nil_value_attribute")) {
|
||||||
|
assertNull(attrValueStatement, attr.getAttributeValue().get(0));
|
||||||
|
} else if (attrName.equals("status")) {
|
||||||
|
assertThat(attrTypeStatement, attr.getAttributeValue().get(0), instanceOf(String.class));
|
||||||
|
String value = (String)attr.getAttributeValue().get(0);
|
||||||
|
assertThat(attrValueStatement, value, containsString("<status><code><status>XYZ</status></code></status>"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("test error: wrong file name to check");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ParsingException.class)
|
||||||
|
public void testSaml20AssertionsNil1() throws IOException, ParsingException {
|
||||||
|
try (InputStream st = SAMLParserTest.class.getResourceAsStream("saml20-assertion-nil-wrong-1.xml")) {
|
||||||
|
parser.parse(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ParsingException.class)
|
||||||
|
public void testSaml20AssertionsNil2() throws IOException, ParsingException {
|
||||||
|
try (InputStream st = SAMLParserTest.class.getResourceAsStream("saml20-assertion-nil-wrong-2.xml")) {
|
||||||
|
parser.parse(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<saml2:Assertion ID="_2fca2bd7a8a8d472d2d35a0d0d75f896" IssueInstant="2017-02-01T15:46:55.938Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">issuer</saml2:Issuer>
|
||||||
|
<saml2:AttributeStatement>
|
||||||
|
<saml2:Attribute Name="attr:type:string" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">CITIZEN</saml2:AttributeValue>
|
||||||
|
</saml2:Attribute>
|
||||||
|
<saml2:Attribute Name="attr:notype:string" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">CITIZEN</saml2:AttributeValue>
|
||||||
|
</saml2:Attribute>
|
||||||
|
<saml2:Attribute Name="attr:notype:element" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<ns4:Name xml:lang="nl" xmlns="urn:be:fgov:ehealth:aa:complextype:v1" xmlns:ns4="urn:be:fgov:ehealth:aa:complextype:v1">hospitaal x</ns4:Name>
|
||||||
|
</saml2:AttributeValue>
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<ns4:Name xml:lang="fr" xmlns="urn:be:fgov:ehealth:aa:complextype:v1" xmlns:ns4="urn:be:fgov:ehealth:aa:complextype:v1">hopital x</ns4:Name>
|
||||||
|
</saml2:AttributeValue>
|
||||||
|
</saml2:Attribute>
|
||||||
|
</saml2:AttributeStatement>
|
||||||
|
</saml2:Assertion>
|
|
@ -0,0 +1,132 @@
|
||||||
|
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
ID="_3c39bc0fe7b13769cab2f6f45eba801b1245264310738"
|
||||||
|
IssueInstant="2009-06-17T18:45:10.738Z" Version="2.0">
|
||||||
|
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
|
||||||
|
https://www.salesforce.com
|
||||||
|
</saml:Issuer>
|
||||||
|
|
||||||
|
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||||
|
<SignedInfo>
|
||||||
|
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
||||||
|
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||||
|
<Reference URI="#_3c39bc0fe7b13769cab2f6f45eba801b1245264310738">
|
||||||
|
<Transforms>
|
||||||
|
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||||
|
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
|
||||||
|
<ec:InclusiveNamespaces PrefixList="ds saml xs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
||||||
|
</Transform>
|
||||||
|
</Transforms>
|
||||||
|
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||||
|
<DigestValue>vzR9Hfp8d16576tEDeq/zhpmLoo=
|
||||||
|
</DigestValue>
|
||||||
|
</Reference>
|
||||||
|
</SignedInfo>
|
||||||
|
<SignatureValue>
|
||||||
|
AzID5hhJeJlG2llUDvZswNUrlrPtR7S37QYH2W+Un1n8c6kTC
|
||||||
|
Xr/lihEKPcA2PZt86eBntFBVDWTRlh/W3yUgGOqQBJMFOVbhK
|
||||||
|
M/CbLHbBUVT5TcxIqvsNvIFdjIGNkf1W0SBqRKZOJ6tzxCcLo
|
||||||
|
9dXqAyAUkqDpX5+AyltwrdCPNmncUM4dtRPjI05CL1rRaGeyX
|
||||||
|
3kkqOL8p0vjm0fazU5tCAJLbYuYgU1LivPSahWNcpvRSlCI4e
|
||||||
|
Pn2oiVDyrcc4et12inPMTc2lGIWWWWJyHOPSiXRSkEAIwQVjf
|
||||||
|
Qm5cpli44Pv8FCrdGWpEE0yXsPBvDkM9jIzwCYGG2fKaLBag==
|
||||||
|
</SignatureValue>
|
||||||
|
<KeyInfo>
|
||||||
|
<X509Data>
|
||||||
|
<X509Certificate>
|
||||||
|
MIIEATCCAumgAwIBAgIBBTANBgkqhkiG9w0BAQ0FADCBgzELM
|
||||||
|
[Certificate truncated for readability...]
|
||||||
|
</X509Certificate>
|
||||||
|
</X509Data>
|
||||||
|
</KeyInfo>
|
||||||
|
</Signature>
|
||||||
|
|
||||||
|
<saml:Subject>
|
||||||
|
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
|
||||||
|
saml01@salesforce.com
|
||||||
|
</saml:NameID>
|
||||||
|
|
||||||
|
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
||||||
|
<saml:SubjectConfirmationData NotOnOrAfter="2009-06-17T18:50:10.738Z"
|
||||||
|
Recipient="https://login.salesforce.com"/>
|
||||||
|
</saml:SubjectConfirmation>
|
||||||
|
</saml:Subject>
|
||||||
|
|
||||||
|
<saml:Conditions NotBefore="2009-06-17T18:45:10.738Z"
|
||||||
|
NotOnOrAfter="2009-06-17T18:50:10.738Z">
|
||||||
|
|
||||||
|
<saml:AudienceRestriction>
|
||||||
|
<saml:Audience>https://saml.salesforce.com</saml:Audience>
|
||||||
|
</saml:AudienceRestriction>
|
||||||
|
</saml:Conditions>
|
||||||
|
|
||||||
|
<saml:AuthnStatement AuthnInstant="2009-06-17T18:45:10.738Z">
|
||||||
|
<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="portal_id">
|
||||||
|
<saml:AttributeValue xsi:type="xs:anyType">060D00000000SHZ
|
||||||
|
</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="organization_id">
|
||||||
|
<saml:AttributeValue xsi:type="xs:anyType">
|
||||||
|
<n1:elem2 xmlns:n1="http://example.net" xml:lang="en">
|
||||||
|
<n3:stuff xmlns:n3="ftp://example.org">00DD0000000F7L5</n3:stuff>
|
||||||
|
</n1:elem2>
|
||||||
|
</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="status">
|
||||||
|
<saml:AttributeValue xsi:type="xs:anyType">
|
||||||
|
<status>
|
||||||
|
<code>
|
||||||
|
<status>XYZ</status>
|
||||||
|
</code>
|
||||||
|
</status>
|
||||||
|
</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="has_sub_organization">
|
||||||
|
<saml:AttributeValue xsi:type="xs:boolean">true</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="anytype_test">
|
||||||
|
<saml:AttributeValue>
|
||||||
|
<elem1 atttr1="en">
|
||||||
|
<elem2>val2</elem2>
|
||||||
|
</elem1>
|
||||||
|
</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="anytype_no_xml_test">
|
||||||
|
<saml:AttributeValue>value_no_xml</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="ssostartpage"
|
||||||
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
|
||||||
|
|
||||||
|
<saml:AttributeValue xsi:type="xs:anyType">
|
||||||
|
http://www.salesforce.com/security/saml/saml20-gen.jsp
|
||||||
|
</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="logouturl"
|
||||||
|
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
|
||||||
|
<saml:AttributeValue xsi:type="xs:string">
|
||||||
|
http://www.salesforce.com/security/del_auth/SsoLogoutPage.html
|
||||||
|
</saml:AttributeValue>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
<saml:Attribute Name="nil_value_attribute">
|
||||||
|
<saml:AttributeValue xsi:nil="true" xsi:type="xs:anyType"/>
|
||||||
|
</saml:Attribute>
|
||||||
|
|
||||||
|
|
||||||
|
</saml:AttributeStatement>
|
||||||
|
</saml:Assertion>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<saml2:Assertion ID="_2fca2bd7a8a8d472d2d35a0d0d75f896" IssueInstant="2017-02-01T15:46:55.938Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">issuer</saml2:Issuer>
|
||||||
|
<saml2:AttributeStatement>
|
||||||
|
<saml2:Attribute Name="attr:type:string" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">CITIZEN</saml2:AttributeValue>
|
||||||
|
</saml2:Attribute>
|
||||||
|
<saml2:Attribute Name="wrong:nil">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="false" xsi:type="xs:anyType"/>
|
||||||
|
</saml2:Attribute>
|
||||||
|
</saml2:AttributeStatement>
|
||||||
|
</saml2:Assertion>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<saml2:Assertion ID="_2fca2bd7a8a8d472d2d35a0d0d75f896" IssueInstant="2017-02-01T15:46:55.938Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">issuer</saml2:Issuer>
|
||||||
|
<saml2:AttributeStatement>
|
||||||
|
<saml2:Attribute Name="attr:type:string" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">CITIZEN</saml2:AttributeValue>
|
||||||
|
</saml2:Attribute>
|
||||||
|
<saml2:Attribute Name="wrong:nil">
|
||||||
|
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="0" xsi:type="xs:anyType"/>
|
||||||
|
</saml2:Attribute>
|
||||||
|
</saml2:AttributeStatement>
|
||||||
|
</saml2:Assertion>
|
Loading…
Reference in a new issue