KEYCLOAK-14698 Support complex SAML Attribute Values (e.g. XUA++)

This commit is contained in:
mwalliczek 2020-07-08 16:50:22 +02:00 committed by Hynek Mlnařík
parent 1c7ad83f90
commit dc73397176
2 changed files with 69 additions and 0 deletions

View file

@ -48,6 +48,8 @@ import org.keycloak.saml.SamlProtocolExtensionsAwareBuilder;
import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.ASSERTION_NSURI;
import static org.keycloak.saml.common.constants.JBossSAMLURIConstants.PROTOCOL_NSURI;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
@ -174,6 +176,8 @@ public class BaseWriter {
writeNameIDTypeAttributeValue((NameIDType) attributeValue);
} else if (attributeValue instanceof XMLGregorianCalendar) {
writeDateAttributeValue((XMLGregorianCalendar) attributeValue);
} else if (attributeValue instanceof Element) {
writeElementAttributeValue((Element) attributeValue);
} else
throw logger.writerUnsupportedAttributeValueError(attributeValue.getClass().getName());
} else {
@ -183,6 +187,13 @@ public class BaseWriter {
}
}
private void writeElementAttributeValue(Element attributeValue) throws ProcessingException {
StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ATTRIBUTE_VALUE.get(),
ASSERTION_NSURI.get());
StaxUtil.writeDOMElement(writer, attributeValue);
StaxUtil.writeEndElement(writer);
}
public void writeNameIDTypeAttributeValue(NameIDType attributeValue) throws ProcessingException {
StaxUtil.writeStartElement(writer, ASSERTION_PREFIX, JBossSAMLConstants.ATTRIBUTE_VALUE.get(), ASSERTION_NSURI.get());
write((NameIDType)attributeValue, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.NAMEID.get(), ASSERTION_PREFIX));

View file

@ -0,0 +1,58 @@
package org.keycloak.saml.processing.core.saml.v2.writers;
import java.io.ByteArrayOutputStream;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
import org.keycloak.dom.saml.v2.assertion.AttributeType;
import org.keycloak.saml.common.constants.GeneralConstants;
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
import org.keycloak.saml.common.exceptions.ConfigurationException;
import org.keycloak.saml.common.exceptions.ProcessingException;
import org.keycloak.saml.common.util.DocumentUtil;
import org.keycloak.saml.common.util.StaxUtil;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XUATokenWriterTest {
@Test
public void testXUAToken() throws ConfigurationException, ProcessingException {
Document document = DocumentUtil.createDocument();
AttributeType roleAttr = new AttributeType("urn:oasis:names:tc:xacml:2.0:subject:role");
Element role = document.createElementNS("urn:hl7-org:v3", "Role");
role.setAttributeNS("urn:hl7-org:v3", "code", "46255001");
role.setAttributeNS("urn:hl7-org:v3", "codeSystem", "2.16.840.1.113883.6.96");
role.setAttributeNS("urn:hl7-org:v3", "codeSystemName", "SNOMED_CT");
role.setAttributeNS("urn:hl7-org:v3", "displayName", "Pharmacist");
Attr attrCEType = document.createAttributeNS(JBossSAMLURIConstants.XSI_NSURI.get(), "type");
attrCEType.setValue("CE");
attrCEType.setPrefix("xsi");
role.setAttributeNodeNS(attrCEType);
roleAttr.addAttributeValue(role);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
SAMLAssertionWriter samlAssertionWriter =
new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(byteArrayOutputStream));
AttributeStatementType attributeStatementType = new AttributeStatementType();
attributeStatementType.addAttribute(new AttributeStatementType.ASTChoiceType(roleAttr));
samlAssertionWriter.write(attributeStatementType);
String serializedAssertion = new String(byteArrayOutputStream.toByteArray(), GeneralConstants.SAML_CHARSET);
Assert.assertEquals("<saml:AttributeStatement>"
+ "<saml:Attribute Name=\"urn:oasis:names:tc:xacml:2.0:subject:role\">"
+ "<saml:AttributeValue>"
+ "<Role xmlns=\"urn:hl7-org:v3\" code=\"46255001\" codeSystem=\"2.16.840.1.113883.6.96\" "
+ "codeSystemName=\"SNOMED_CT\" displayName=\"Pharmacist\" "
+ "xsi:type=\"CE\"></Role></saml:AttributeValue></saml:Attribute>"
+ "</saml:AttributeStatement>",
serializedAssertion);
}
}