public void ClaimsIdentityExtensions_ToSaml2Assertion_MultipleValuesForSameKey_CombinesTo_OneAttribute() { var ci = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.NameIdentifier, "JohnDoe"), new Claim(ClaimTypes.Role, "Test1"), new Claim(ClaimTypes.Role, "Test2"), }); var assertion = ci.ToSaml2Assertion(new EntityId("http://idp.example.com")); assertion.Statements.OfType<Saml2AttributeStatement>().Should().HaveCount(1); var actual = assertion.Statements.OfType<Saml2AttributeStatement>().Single(); var expected = new Saml2AttributeStatement( new Saml2Attribute(ClaimTypes.Role, new[] { "Test1", "Test2" })); actual.ShouldBeEquivalentTo(expected); }
private static XElement ToXElement(Saml2AttributeStatement attributeStatement) { var element = new XElement(Saml2Namespaces.Saml2 + "AttributeStatement"); foreach (var attribute in attributeStatement.Attributes) { var attributeElement = new XElement(Saml2Namespaces.Saml2 + "Attribute", new XAttribute("Name", attribute.Name)); attributeElement.AddAttributeIfNotNullOrEmpty("FriendlyName", attribute.FriendlyName); attributeElement.AddAttributeIfNotNullOrEmpty("NameFormat", attribute.NameFormat); attributeElement.AddAttributeIfNotNullOrEmpty("OriginalIssuer", attribute.OriginalIssuer); foreach (var value in attribute.Values) { attributeElement.Add(new XElement(Saml2Namespaces.Saml2 + "AttributeValue", value)); } element.Add(attributeElement); } return element; }
/// <summary> /// Writes the <saml:AttributeStatement> element. /// </summary> /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2AttributeStatement"/>.</param> /// <param name="data">The <see cref="Saml2AttributeStatement"/> to serialize.</param> protected virtual void WriteAttributeStatement(XmlWriter writer, Saml2AttributeStatement data) { if (null == writer) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); } if (null == data) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("data"); } if (data.Attributes == null || 0 == data.Attributes.Count) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4124))); } // <AttributeStatement> writer.WriteStartElement(Saml2Constants.Elements.AttributeStatement, Saml2Constants.Namespace); // <Attribute> 1-OO foreach (Saml2Attribute attribute in data.Attributes) { this.WriteAttribute(writer, attribute); } // </AttributeStatement> writer.WriteEndElement(); }
/// <summary> /// Reads the <saml:AttributeStatement> element, or a /// <saml:Statement element that specifies an xsi:type of /// saml:AttributeStatementType. /// </summary> /// <param name="reader">A <see cref="XmlReader"/> positioned at a <see cref="Saml2AttributeStatement"/> element.</param> /// <returns>A <see cref="Saml2AttributeStatement"/> instance.</returns> protected virtual Saml2AttributeStatement ReadAttributeStatement(XmlReader reader) { if (null == reader) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); } // throw if wrong element bool isStatementElement = false; if (reader.IsStartElement(Saml2Constants.Elements.Statement, Saml2Constants.Namespace)) { isStatementElement = true; } else if (!reader.IsStartElement(Saml2Constants.Elements.AttributeStatement, Saml2Constants.Namespace)) { reader.ReadStartElement(Saml2Constants.Elements.AttributeStatement, Saml2Constants.Namespace); } try { // defer disallowing empty element until checking xsi:type bool isEmpty = reader.IsEmptyElement; // @attributes // @xsi:type XmlUtil.ValidateXsiType(reader, Saml2Constants.Types.AttributeStatementType, Saml2Constants.Namespace, isStatementElement); // disallow empty element, since xsi:type is ok if (isEmpty) { throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID3061, Saml2Constants.Elements.AttributeStatement, Saml2Constants.Namespace)); } // Content Saml2AttributeStatement statement = new Saml2AttributeStatement(); reader.Read(); // <Attribute|EncryptedAttribute> 1-OO while (reader.IsStartElement()) { if (reader.IsStartElement(Saml2Constants.Elements.EncryptedAttribute, Saml2Constants.Namespace)) { throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID4158)); } else if (reader.IsStartElement(Saml2Constants.Elements.Attribute, Saml2Constants.Namespace)) { statement.Attributes.Add(this.ReadAttribute(reader)); } else { break; } } // At least one attribute expected if (0 == statement.Attributes.Count) { reader.ReadStartElement(Saml2Constants.Elements.Attribute, Saml2Constants.Namespace); } reader.ReadEndElement(); return statement; } catch (Exception e) { if (System.Runtime.Fx.IsFatal(e)) throw; Exception wrapped = TryWrapReadException(reader, e); if (null == wrapped) { throw; } else { throw wrapped; } } }
/// <summary> /// Creates claims from a Saml2AttributeStatement. /// </summary> /// <param name="statement">The Saml2AttributeStatement.</param> /// <param name="subject">The subject.</param> /// <param name="issuer">The issuer.</param> protected virtual void ProcessAttributeStatement(Saml2AttributeStatement statement, ClaimsIdentity subject, string issuer) { if (statement == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("statement"); } if (subject == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("subject"); } foreach (Saml2Attribute attribute in statement.Attributes) { if (StringComparer.Ordinal.Equals(attribute.Name, ClaimTypes.Actor)) { if (subject.Actor != null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4218)); } this.SetDelegateFromAttribute(attribute, subject, issuer); } else { foreach (string value in attribute.Values) { if (value != null) { string originalIssuer = issuer; if (attribute.OriginalIssuer != null) { originalIssuer = attribute.OriginalIssuer; } Claim claim = new Claim(attribute.Name, value, attribute.AttributeValueXsiType, issuer, originalIssuer); if (attribute.NameFormat != null) { claim.Properties[ClaimProperties.SamlAttributeNameFormat] = attribute.NameFormat.AbsoluteUri; } if (attribute.FriendlyName != null) { claim.Properties[ClaimProperties.SamlAttributeDisplayName] = attribute.FriendlyName; } subject.AddClaim(claim); } } } } }