I want to generate saml as below and I tried code for such requirement-I want such list structure to generate as mentioned below in SAMl I want) as mentioned in earlier post from your Forum--
https://www.componentspace.com/Forums/5463/XML-as-a-SAML-Attribute-Value<saml:Assertion Version="2.0" ID="12345" IssueInstant="2018-04-28T17:10:44Z"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:AttributeStatement>
<saml:Attribute Name="Employees" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="Employees">
<saml:AttributeValue>
<Employee>Employee1</Employee>
<Department>Department1</Department>
</saml:AttributeValue>
<saml:AttributeValue>
<Employee>Employee2</Employee>
<Department>Department2</Department>
</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
1. For this I am generating list in my custom object first from data.
I have class (Custom)as below
public class SAMLModuleAttribute
{
public SAMLModuleAttribute()
{
}
public SAMLModuleAttribute(string attributename, string friendlyname, string attributevalue)
{
this.AttributeName = attributename;
this.FriendlyName = friendlyname;
this.AttributeValue = attributevalue;
}
public string AttributeName { get; set; }
public string FriendlyName { get; set; }
public string AttributeValue { get; set; }
public List<SAMLModuleAttributeValue> AttributeValues { get; set; }
}
Then I am using it to generate below Object structure
var lstAttributes =List<SAMLModuleAttribute>();
var samlAttribute = new SAMLModuleAttribute("Employees", "","");
samlAttribute.AttributeValues = new List<SAMLModuleAttributeValue>();
foreach (var employee in employeeList)
{
samlAttribute.AttributeValues.Add(new SAMLModuleAttributeValue
{
Name = "Employee",
Value = "Employee1"
});
samlAttribute.AttributeValues.Add(new SAMLModuleAttributeValue
{
Name = "Department",
Value = "Department1"
});
}
lstAttributes.Add(samlAttribute);
2. Then I am passing it to first fill it in Saml low lecvel api of componenet space using AttributeStatement
AttributeStatement attStatement = new AttributeStatement();
CreateMultiValueSAMLAttributes(lstAttributes,attStatement);
private void CreateMultiValueSAMLAttributes(List<SAMLModuleAttribute> lstAttributes, AttributeStatement attStatement)
SAMLAttribute.RegisterAttributeValueSerializer("Employees", null, new XmlAttributeValueSerializer());
foreach (SAMLModuleAttribute attb in lstAttributes)
{
SAMLAttribute attrib = new SAMLAttribute(attb.AttributeName, SAMLIdentifiers.AttributeNameFormats.Basic,
attb.FriendlyName, attb.AttributeValue);
if (attb.AttributeValues != null && attb.AttributeValues.Count > 0)
{
XmlDocument doc = new XmlDocument();
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
XmlElement employeeElement = doc.CreateElement(string.Empty, "Employees", string.Empty);
doc.AppendChild(employeeElement);
foreach (var attrinuteValue in attb.AttributeValues)
{
XmlElement attributeValueNode = doc.CreateElement(string.Empty, attrinuteValue.Name, string.Empty);
XmlText attributeValue = doc.CreateTextNode(attrinuteValue.Value);
attributeValueNode.AppendChild(attributeValue);
accountElement.AppendChild(attributeValueNode);
///The Above code will add Xml Strucure like when loop completes <Employee>Employee1<Employee> <Department>Department1<Department> <Employee>Employee2<Employee> <Department>Department2<Department>
// inside<Employees> parent node
XmlElement employeeNode = doc.CreateElement(string.Empty, "Employee", string.Empty);
XmlText attributeValue = doc.CreateTextNode("Employee1";
employeeNode.AppendChild(attributeValue);
XmlElement deptNode = doc.CreateElement(string.Empty, "Department", string.Empty);
XmlText attributeValue = doc.CreateTextNode("Department1";
deptNode.AppendChild(attributeValue);
}
var xmlDocument = new XmlDocument();
xmldocument.PreserveWhitespace = true;
xmldocument.LoadXml(doc.DocumentElement.OuterXml);
attrib.Values.Add(new AttributeValue(xmldocument.DocumentElement));
}
attStatement.Attributes.Add(attrib);
}
}
And finally I am using To Xml on SamlAssertion to get Saml string from it
SAMLAssertion samlAssertion = new SAMLAssertion();
--code to fill Saml Assertion
samlAssertion.Statements.Add(attStatement);
string samlString= samlAssertion.ToXml().OuterXml.ToString();
But above line generates saml as below
Actual SAMl I am getting
<saml:Assertion Version="2.0" ID="12345" IssueInstant="2018-04-28T17:10:44Z"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:AttributeStatement>
<saml:Attribute Name="Employees" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="Employees">
<saml:AttributeValue></saml:AttributeValue>
<saml:AttributeValue>System.Xml.XmlElement</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
Instead of below which is expected
<saml:Assertion Version="2.0" ID="12345" IssueInstant="2018-04-28T17:10:44Z"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:AttributeStatement>
<saml:Attribute Name="Employees" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" FriendlyName="Employees">
<saml:AttributeValue>
<Employee>Employee1</Employee>
<Department>Department1</Department>
</saml:AttributeValue>
<saml:AttributeValue>
<Employee>Employee2</Employee>
<Department>Department2</Department>
</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
It seems it cannot serlize it properly the InnerXml under parent EMployees node and genartes incorrect xml as <saml:AttributeValue>System.Xml.XmlElement</saml:AttributeValue>
Can you please help to resolve this.