ComponentSpace

Forums



XML as a SAML Attribute Value


XML as a SAML Attribute Value

Author
Message
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)

Group: Administrators
Posts: 2K, Visits: 4.6K
Most SAML attribute values are simple string values. For example:

<saml:Attribute Name="support-email">
    <saml:AttributeValue>support@componentspace.com</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="sales-email">
    <saml:AttributeValue>sales@componentspace.com</saml:AttributeValue>
</saml:Attribute>



However, it's also possible to specify XML as the SAML attribute value. For example:

<saml:Attribute Name="email-addresses">
    <saml:AttributeValue>
        <support-email>support@componentspace.com</support-email>
        <sales-email>sales@componentspace.com</sales-email>
    </saml:AttributeValue>
</saml:Attribute>



The following code calls the SAML high-level API and includes an attribute whose value is XML.

var attributes = new Dictionary<string, string>();

var xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.LoadXml("<email-addresses><support-email>support@componentspace.com</support-email><sales-email>sales@componentspace.com</sales-email></email-addresses>");

attributes["email-addresses"] = xmlDocument.DocumentElement.FirstChild.OuterXml;

SAMLIdentityProvider.SendSSO(Response, userName, attributes);



The equivalent code using the SAML low-level API is:


var attributeStatement = new AttributeStatement();
SAMLAttribute.RegisterAttributeValueSerializer("email-addresses", null, new XmlAttributeValueSerializer());
var samlAttribute = new SAMLAttribute("email-addresses", null, null);

var xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.LoadXml("<email-addresses><support-email>support@componentspace.com</support-email><sales-email>sales@componentspace.com</sales-email></email-addresses>");

samlAttribute.Values.Add(new AttributeValue(xmlDocument.DocumentElement.FirstChild));
attributeStatement.Attributes.Add(samlAttribute);




Regards
ComponentSpace Development
Amol
Amol
New Member
New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)

Group: Forum Members
Posts: 7, Visits: 47
[quote]
ComponentSpace - 9/30/2016
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.

ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)

Group: Administrators
Posts: 2K, Visits: 4.6K
The following code generates the required XML.
For brevity, it loads the attribute values XML from strings but you can construct these however you wish.


// Employees attribute values are to be serialized as XML.
SAMLAttribute.RegisterAttributeValueSerializer("Employees", null, new XmlAttributeValueSerializer());

// Load some test employee records.
var xmlDocument = new XmlDocument()
{
  PreserveWhitespace = true
};

xmlDocument.LoadXml("<EmployeeRecord><Employee>Employee1</Employee><Department>Department1</Department></EmployeeRecord>");
var employee1 = xmlDocument.DocumentElement.ChildNodes;

xmlDocument.LoadXml("<EmployeeRecord><Employee>Employee2</Employee><Department>Department2</Department></EmployeeRecord>");
var employee2 = xmlDocument.DocumentElement.ChildNodes;

// Create the example SAML assertion.
var samlAssertion = new SAMLAssertion();
samlAssertion.Statements.Add(new AttributeStatement()
{
  Attributes = new ArrayList()
  {
   new SAMLAttribute()
   {
    Name = "Employees",
    FriendlyName = "Employees",
    NameFormat = SAMLIdentifiers.AttributeNameFormats.Basic,
    Values = new List<AttributeValue>()
    {
      new AttributeValue()
      {
       Data = employee1
      },
      new AttributeValue()
      {
       Data = employee2
      }
    }
   }
  }
});

// Serialize the SAMl assertion to an XML string.
var xmlText = samlAssertion.ToString();




Regards
ComponentSpace Development
Amol
Amol
New Member
New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)

Group: Forum Members
Posts: 7, Visits: 47
ComponentSpace - 4/28/2018
The following code generates the required XML.
For brevity, it loads the attribute values XML from strings but you can construct these however you wish.


// Employees attribute values are to be serialized as XML.
SAMLAttribute.RegisterAttributeValueSerializer("Employees", null, new XmlAttributeValueSerializer());

// Load some test employee records.
var xmlDocument = new XmlDocument()
{
  PreserveWhitespace = true
};

xmldocument.LoadXml("<EmployeeRecord><Employee>Employee1</Employee><Department>Department1</Department></EmployeeRecord>");
var employee1 = xmldocument.DocumentElement.ChildNodes;

xmldocument.LoadXml("<EmployeeRecord><Employee>Employee2</Employee><Department>Department2</Department></EmployeeRecord>");
var employee2 = xmldocument.DocumentElement.ChildNodes;

// Create the example SAML assertion.
var samlAssertion = new SAMLAssertion();
samlAssertion.Statements.Add(new AttributeStatement()
{
  Attributes = new ArrayList()
  {
   new SAMLAttribute()
   {
    Name = "Employees",
    FriendlyName = "Employees",
    NameFormat = SAMLIdentifiers.AttributeNameFormats.Basic,
    Values = new List<AttributeValue>()
    {
      new AttributeValue()
      {
       Data = employee1
      },
      new AttributeValue()
      {
       Data = employee2
      }
    }
   }
  }
});

// Serialize the SAMl assertion to an XML string.
var xmlText = samlAssertion.ToString();



Hi Mitchell ,

I tried it but the last line var xmlText = samlAssertion.ToString(); gives me output ComponentSpace.SAML2.Assertions.SAMLAssertion.
And when I tried  samlAssertion.ToXml() or samlAssertion.ToXml().OuterXml  it gives below exception during Serlization 

"Unable to cast object of type 'System.Xml.XmlChildNodes' to type 'System.Xml.XmlElement'."}System.Exception {System.InvalidCastException
'samlAssertion.ToXml()' threw an exception of type 'ComponentSpace.SAML2.SAMLSerializationException'

It seems it cannot serilize it properly.
If you run the code you shared you will get the above output i.e.
xmlText = samlAssertion.ToString(); gives me output ComponentSpace.SAML2.Assertions.SAMLAssertion.
And
xmlText = samlAssertion.ToXml(); gives exception
"Unable to cast object of type 'System.Xml.XmlChildNodes' to type 'System.Xml.XmlElement'."}System.Exception {System.InvalidCastException

Please help me to resolve this.

Thanks,
Amol





ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)

Group: Administrators
Posts: 2K, Visits: 4.6K
What version of the product are you using?
https://www.componentspace.com/Forums/31/Determining-the-Component-Version-and-License


Regards
ComponentSpace Development
Amol
Amol
New Member
New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)New Member (9 reputation)

Group: Forum Members
Posts: 7, Visits: 47
ComponentSpace - 4/29/2018

I am using 2.1.0.4
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)ComponentSpace Development (2.9K reputation)

Group: Administrators
Posts: 2K, Visits: 4.6K
That version is almost 10 years old.
You should upgrade to pick up the latest functionality.
https://www.componentspace.com/Forums/8576/Release-Notes


Regards
ComponentSpace Development
GO


Similar Topics


Execution: 0.000. 2 queries. Compression Enabled.
Login
Existing Account
Email Address:


Password:


Social Logins

Select a Forum....









ComponentSpace Forums


Search