public virtual SamlAttribute LoadAttribute(XmlDictionaryReader reader, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            SamlAttribute attribute = new SamlAttribute();

            attribute.ReadXml(reader, this, keyInfoSerializer, outOfBandTokenResolver);
            return(attribute);
        }
Ejemplo n.º 2
0
 public static IList<string> GetValuesFor(SamlAttribute attribute)
 {
   IList<string> values = new List<string>();
   foreach (string value in attribute.AttributeValues) {
     values.Add(value);
   }
   return values;
 }
        public override void ReadXml(XmlDictionaryReader reader, SamlSerializer samlSerializer, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("reader"));
            }

            if (samlSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("samlSerializer"));
            }

#pragma warning suppress 56506 // samlSerializer.DictionaryManager is never null.
            SamlDictionary dictionary = samlSerializer.DictionaryManager.SamlDictionary;

            reader.MoveToContent();
            reader.Read();

            if (reader.IsStartElement(dictionary.Subject, dictionary.Namespace))
            {
                SamlSubject subject = new SamlSubject();
                subject.ReadXml(reader, samlSerializer, keyInfoSerializer, outOfBandTokenResolver);
                base.SamlSubject = subject;
            }
            else
            {
                // SAML Subject is a required Attribute Statement clause.
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLAttributeStatementMissingSubjectOnRead)));
            }

            while (reader.IsStartElement())
            {
                if (reader.IsStartElement(dictionary.Attribute, dictionary.Namespace))
                {
                    // SAML Attribute is a extensibility point. So ask the SAML serializer
                    // to load this part.
                    SamlAttribute attribute = samlSerializer.LoadAttribute(reader, keyInfoSerializer, outOfBandTokenResolver);
                    if (attribute == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLUnableToLoadAttribute)));
                    }
                    this.attributes.Add(attribute);
                }
                else
                {
                    break;
                }
            }

            if (this.attributes.Count == 0)
            {
                // Each Attribute statement should have at least one attribute.
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SAMLAttributeStatementMissingAttributeOnRead)));
            }

            reader.MoveToContent();
            reader.ReadEndElement();
        }
Ejemplo n.º 4
0
		public void WriteXml1 ()
		{
			SamlAttribute attr = new SamlAttribute (Claim.CreateNameClaim ("myname"));
			SamlSubject subject = new SamlSubject (
				SamlConstants.UserNameNamespace,
				"urn:myqualifier",
				"myname");
			SamlAttributeStatement s = new SamlAttributeStatement (
				subject, new SamlAttribute [] {attr});
			StringWriter sw = new StringWriter ();
			using (XmlDictionaryWriter dw = CreateWriter (sw)) {
				s.WriteXml (dw, new SamlSerializer (), null);
			}
			Assert.AreEqual (String.Format ("<?xml version=\"1.0\" encoding=\"utf-16\"?><saml:AttributeStatement xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\"><saml:Subject><saml:NameIdentifier Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName\" NameQualifier=\"urn:myqualifier\">myname</saml:NameIdentifier></saml:Subject><saml:Attribute AttributeName=\"name\" AttributeNamespace=\"{0}\"><saml:AttributeValue>myname</saml:AttributeValue></saml:Attribute></saml:AttributeStatement>", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims"), sw.ToString ());
		}
Ejemplo n.º 5
0
            public AttributeKey(SamlAttribute attribute)
            {
                if (attribute == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("attribute");
                }

                _friendlyName   = String.Empty;
                _name           = attribute.Name;
                _nameFormat     = String.Empty;
                _namespace      = attribute.Namespace ?? String.Empty;
                _valueType      = attribute.AttributeValueXsiType ?? String.Empty;
                _originalIssuer = attribute.OriginalIssuer ?? String.Empty;

                ComputeHashCode();
            }
Ejemplo n.º 6
0
        public override void ReadXml(XmlDictionaryReader reader, SamlSerializer samlSerializer, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("reader"));
            }
            if (samlSerializer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("samlSerializer"));
            }
            SamlDictionary samlDictionary = samlSerializer.DictionaryManager.SamlDictionary;

            reader.MoveToContent();
            reader.Read();
            if (!reader.IsStartElement(samlDictionary.Subject, samlDictionary.Namespace))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SAMLAttributeStatementMissingSubjectOnRead")));
            }
            SamlSubject subject = new SamlSubject();

            subject.ReadXml(reader, samlSerializer, keyInfoSerializer, outOfBandTokenResolver);
            base.SamlSubject = subject;
            while (reader.IsStartElement())
            {
                if (!reader.IsStartElement(samlDictionary.Attribute, samlDictionary.Namespace))
                {
                    break;
                }
                SamlAttribute item = samlSerializer.LoadAttribute(reader, keyInfoSerializer, outOfBandTokenResolver);
                if (item == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SAMLUnableToLoadAttribute")));
                }
                this.attributes.Add(item);
            }
            if (this.attributes.Count == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SAMLAttributeStatementMissingAttributeOnRead")));
            }
            reader.MoveToContent();
            reader.ReadEndElement();
        }
		SamlSecurityToken GetSamlToken ()
		{
			SamlAssertion a = new SamlAssertion ();
			
			SamlSubject subject = new SamlSubject (
				SamlConstants.UserNameNamespace,
				"urn:myqualifier",
				"myname");
			SamlAttribute attr = new SamlAttribute (Claim.CreateNameClaim ("myname"));
			SamlAttributeStatement statement =
				new SamlAttributeStatement (subject, new SamlAttribute [] {attr});
			a.Statements.Add (statement);
			a.Issuer = "my_hero";

			X509Certificate2 cert = new X509Certificate2 ("Test/Resources/test.pfx", "mono");
			X509AsymmetricSecurityKey key =
				new X509AsymmetricSecurityKey (cert);
			a.SigningCredentials =
				new SigningCredentials (key,
					SecurityAlgorithms.HmacSha1Signature, 
					SecurityAlgorithms.Sha256Digest);
			XmlDocument doc = new XmlDocument ();
			XmlWriter w = doc.CreateNavigator ().AppendChild ();
			using (XmlDictionaryWriter dw = XmlDictionaryWriter.CreateDictionaryWriter (w)) {
				a.WriteXml (dw, new SamlSerializer (), new MySecurityTokenSerializer ());
			}
Console.Error.WriteLine (doc.OuterXml);
			return new SamlSecurityToken (a);

		}
Ejemplo n.º 8
0
		public void ConstructorNullSubject ()
		{
			SamlAttribute attr = new SamlAttribute (Claim.CreateNameClaim ("myname"));
			new SamlAttributeStatement (null, new SamlAttribute [] {attr});
		}
        /// <summary>
        /// Generates a SamlAttribute from a claim.
        /// </summary>
        /// <param name="claim">Claim from which to generate a SamlAttribute.</param>
        /// <param name="tokenDescriptor">Contains all the information that is used in token issuance.</param>
        /// <returns>The SamlAttribute.</returns>
        /// <exception cref="ArgumentNullException">The parameter 'claim' is null.</exception>
        protected virtual SamlAttribute CreateAttribute(Claim claim, SecurityTokenDescriptor tokenDescriptor)
        {
            if (claim == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim");
            }

            int lastSlashIndex = claim.Type.LastIndexOf('/');
            string attributeNamespace = null;
            string attributeName = null;

            if ((lastSlashIndex == 0) || (lastSlashIndex == -1))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("claimType", SR.GetString(SR.ID4216, claim.Type));
            }
            else if (lastSlashIndex == claim.Type.Length - 1)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("claimType", SR.GetString(SR.ID4216, claim.Type));
            }
            else
            {
                attributeNamespace = claim.Type.Substring(0, lastSlashIndex);
                //
                // The WCF SamlAttribute requires that the attributeNamespace and attributeName are both non-null and non-empty. 
                // Furthermore, on deserialization / construction it considers the claimType associated with the SamlAttribute to be attributeNamespace + "/" + attributeName. 
                //
                // IDFX extends the WCF SamlAttribute and hence has to work with an attributeNamespace and attributeName that are both non-null and non-empty. 
                // On serialization, we identify the last slash in the claimtype, and treat everything before the slash as the attributeNamespace and everything after the slash as the attributeName. 
                // On deserialization, we don't always insert a "/" between the attributeNamespace and attributeName (like WCF does); we only do so if the attributeNamespace doesn't have a trailing slash.
                //
                // Send     Receive     Behavior
                // =============================
                // WCF      WCF         Works as expected
                //
                // WCF      IDFX        In the common case (http://www.claimtypes.com/foo), WCF will not send a trailing slash in the attributeNamespace. IDFX will add one upon deserialization.
                //                      In the edge case (http://www.claimtypes.com//foo), WCF will send a trailing slash in the attributeNamespace. IDFX will not add one upon deserialization.
                //
                // IDFX     WCF         In the common case (http://www.claimtypes.com/foo), IDFX will not send a trailing slash. WCF will add one upon deserialization.
                //                      In the edge case (http://www.claimtypes.com//foo), IDFX will throw (which is what the fix for FIP 6301 is about).
                //
                // IDFX     IDFX        Works as expected
                //
                if (attributeNamespace.EndsWith("/", StringComparison.Ordinal))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("claim", SR.GetString(SR.ID4213, claim.Type));
                }
                attributeName = claim.Type.Substring(lastSlashIndex + 1, claim.Type.Length - (lastSlashIndex + 1));
            }

            SamlAttribute attribute = new SamlAttribute(attributeNamespace, attributeName, new string[] { claim.Value });
            if (!StringComparer.Ordinal.Equals(ClaimsIdentity.DefaultIssuer, claim.OriginalIssuer))
            {
                attribute.OriginalIssuer = claim.OriginalIssuer;
            }
            attribute.AttributeValueXsiType = claim.ValueType;

            return attribute;
        }
        /// <summary>
        /// Writes the saml:Attribute value.
        /// </summary>
        /// <param name="writer">XmlWriter to which to write.</param>
        /// <param name="value">Attribute value to be written.</param>
        /// <param name="attribute">The SAML attribute whose value is being written.</param>
        /// <remarks>By default the method writes the value as a string.</remarks>
        /// <exception cref="ArgumentNullException">The input parameter 'writer' is null.</exception>
        protected virtual void WriteAttributeValue(XmlWriter writer, string value, SamlAttribute attribute)
        {
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            writer.WriteString(value);
        }
        /// <summary>
        /// Serializes a given SamlAttribute.
        /// </summary>
        /// <param name="writer">XmlWriter to serialize the SamlAttribute.</param>
        /// <param name="attribute">SamlAttribute to be serialized.</param>
        /// <exception cref="ArgumentNullException">The input parameter 'writer' or 'attribute' is null.</exception>
        protected virtual void WriteAttribute(XmlWriter writer, SamlAttribute attribute)
        {
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (attribute == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("attribute");
            }

            writer.WriteStartElement(SamlConstants.Prefix, SamlConstants.ElementNames.Attribute, SamlConstants.Namespace);

            writer.WriteAttributeString(SamlConstants.AttributeNames.AttributeName, null, attribute.Name);
            writer.WriteAttributeString(SamlConstants.AttributeNames.AttributeNamespace, null, attribute.Namespace);

            SamlAttribute SamlAttribute = attribute as SamlAttribute;
            if ((SamlAttribute != null) && (SamlAttribute.OriginalIssuer != null))
            {
                writer.WriteAttributeString(SamlConstants.AttributeNames.OriginalIssuer, ClaimType2009Namespace, SamlAttribute.OriginalIssuer);
            }

            string xsiTypePrefix = null;
            string xsiTypeSuffix = null;
            if (SamlAttribute != null && !StringComparer.Ordinal.Equals(SamlAttribute.AttributeValueXsiType, ClaimValueTypes.String))
            {
                // ClaimValueTypes are URIs of the form prefix#suffix, while xsi:type should be a QName.
                // Hence, the tokens-to-claims spec requires that ClaimValueTypes be serialized as xmlns:tn="prefix" xsi:type="tn:suffix"
                int indexOfHash = SamlAttribute.AttributeValueXsiType.IndexOf('#');
                xsiTypePrefix = SamlAttribute.AttributeValueXsiType.Substring(0, indexOfHash);
                xsiTypeSuffix = SamlAttribute.AttributeValueXsiType.Substring(indexOfHash + 1);
            }

            for (int i = 0; i < attribute.AttributeValues.Count; i++)
            {
                if (attribute.AttributeValues[i] == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4096)));
                }

                writer.WriteStartElement(SamlConstants.Prefix, SamlConstants.ElementNames.AttributeValue, SamlConstants.Namespace);
                if ((xsiTypePrefix != null) && (xsiTypeSuffix != null))
                {
                    writer.WriteAttributeString("xmlns", ProductConstants.ClaimValueTypeSerializationPrefix, null, xsiTypePrefix);
                    writer.WriteAttributeString("type", XmlSchema.InstanceNamespace, String.Concat(ProductConstants.ClaimValueTypeSerializationPrefixWithColon, xsiTypeSuffix));
                }
                WriteAttributeValue(writer, attribute.AttributeValues[i], attribute);
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
        }
        /// <summary>
        /// Reads an attribute value.
        /// </summary>
        /// <param name="reader">XmlReader to read from.</param>
        /// <param name="attribute">The current attribute that is being read.</param>
        /// <returns>The attribute value as a string.</returns>
        /// <exception cref="ArgumentNullException">The input parameter 'reader' is null.</exception>
        protected virtual string ReadAttributeValue(XmlReader reader, SamlAttribute attribute)
        {
            // This code was designed realizing that the writter of the xml controls how our
            // reader will report the NodeType. A completely differnet system (IBM, etc) could write the values. 
            // Considering NodeType is important, because we need to read the entire value, end element and not loose anything significant.
            // 
            // Couple of cases to help understand the design choices.
            //
            // 1. 
            // "<MyElement xmlns=""urn:mynamespace""><another>complex</another></MyElement><sibling>value</sibling>"
            // Could result in the our reader reporting the NodeType as Text OR Element, depending if '<' was entitized to '&lt;'
            //
            // 2. 
            // " <MyElement xmlns=""urn:mynamespace""><another>complex</another></MyElement><sibling>value</sibling>"
            // Could result in the our reader reporting the NodeType as Text OR Whitespace.  Post Whitespace processing, the NodeType could be 
            // reported as Text or Element, depending if '<' was entitized to '&lt;'
            //
            // 3. 
            // "/r/n/t   "
            // Could result in the our reader reporting the NodeType as whitespace.
            //
            // Since an AttributeValue with ONLY Whitespace and a complex Element proceeded by whitespace are reported as the same NodeType (2. and 3.)
            // the whitespace is remembered and discarded if an found is found, otherwise it becomes the value. This is to help users who accidently put a space when adding claims in ADFS
            // If we just skipped the Whitespace, then an AttributeValue that started with Whitespace would loose that part and claims generated from the AttributeValue
            // would be missing that part.
            // 

            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            string result = String.Empty;
            string whiteSpace = String.Empty;

            reader.ReadStartElement(Saml2Constants.Elements.AttributeValue, SamlConstants.Namespace);

            while (reader.NodeType == XmlNodeType.Whitespace)
            {
                whiteSpace += reader.Value;
                reader.Read();
            }

            reader.MoveToContent();
            if (reader.NodeType == XmlNodeType.Element)
            {
                while (reader.NodeType == XmlNodeType.Element)
                {
                    result += reader.ReadOuterXml();
                    reader.MoveToContent();
                }
            }
            else
            {
                result = whiteSpace;
                result += reader.ReadContentAsString();
            }

            reader.ReadEndElement();
            return result;
        }
        /// <summary>
        /// Read an saml:Attribute element.
        /// </summary>
        /// <param name="reader">XmlReader positioned at a saml:Attribute element.</param>
        /// <returns>SamlAttribute</returns>
        /// <exception cref="ArgumentNullException">The input parameter 'reader' is null.</exception>
        /// <exception cref="XmlException">The XmlReader is not positioned on a valid saml:Attribute element.</exception>
        protected virtual SamlAttribute ReadAttribute(XmlReader reader)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            SamlAttribute attribute = new SamlAttribute();

            attribute.Name = reader.GetAttribute(SamlConstants.AttributeNames.AttributeName, null);
            if (string.IsNullOrEmpty(attribute.Name))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ID4094)));
            }

            attribute.Namespace = reader.GetAttribute(SamlConstants.AttributeNames.AttributeNamespace, null);
            if (string.IsNullOrEmpty(attribute.Namespace))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ID4095)));
            }

            //
            // OriginalIssuer is an optional attribute.
            // We are lax on read here, and will accept the following namespaces for original issuer, in order:
            // http://schemas.xmlsoap.org/ws/2009/09/identity/claims
            // http://schemas.microsoft.com/ws/2008/06/identity
            //
            string originalIssuer = reader.GetAttribute(SamlConstants.AttributeNames.OriginalIssuer, ClaimType2009Namespace);

            if (originalIssuer == null)
            {
                originalIssuer = reader.GetAttribute(SamlConstants.AttributeNames.OriginalIssuer, ProductConstants.NamespaceUri);
            }

            if (originalIssuer == String.Empty)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ID4252)));
            }
            attribute.OriginalIssuer = originalIssuer;

            reader.MoveToContent();
            reader.Read();
            while (reader.IsStartElement(SamlConstants.ElementNames.AttributeValue, SamlConstants.Namespace))
            {
                // FIP 9570 - ENTERPRISE SCENARIO: Saml11SecurityTokenHandler.ReadAttribute is not checking the AttributeValue XSI type correctly.
                // Lax on receive. If we dont find the AttributeValueXsiType in the format we are looking for in the xml, we default to string.
                // Read the xsi:type. We are expecting a value of the form "some-non-empty-string" or "some-non-empty-local-prefix:some-non-empty-string".
                // ":some-non-empty-string" and "some-non-empty-string:" are edge-cases where defaulting to string is reasonable.
                string attributeValueXsiTypePrefix = null;
                string attributeValueXsiTypeSuffix = null;
                string attributeValueXsiTypeSuffixWithLocalPrefix = reader.GetAttribute("type", XmlSchema.InstanceNamespace);
                if (!string.IsNullOrEmpty(attributeValueXsiTypeSuffixWithLocalPrefix))
                {
                    if (attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) == -1) // "some-non-empty-string" case
                    {
                        attributeValueXsiTypePrefix = reader.LookupNamespace(String.Empty);
                        attributeValueXsiTypeSuffix = attributeValueXsiTypeSuffixWithLocalPrefix;
                    }
                    else if (attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) > 0 &&
                              attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) < attributeValueXsiTypeSuffixWithLocalPrefix.Length - 1) // "some-non-empty-local-prefix:some-non-empty-string" case
                    {
                        string localPrefix = attributeValueXsiTypeSuffixWithLocalPrefix.Substring(0, attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal));
                        attributeValueXsiTypePrefix = reader.LookupNamespace(localPrefix);
                        // For attributeValueXsiTypeSuffix, we want the portion after the local prefix in "some-non-empty-local-prefix:some-non-empty-string"
                        attributeValueXsiTypeSuffix = attributeValueXsiTypeSuffixWithLocalPrefix.Substring(attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) + 1);
                    }
                }
                if (attributeValueXsiTypePrefix != null && attributeValueXsiTypeSuffix != null)
                {
                    attribute.AttributeValueXsiType = String.Concat(attributeValueXsiTypePrefix, "#", attributeValueXsiTypeSuffix);
                }

                if (reader.IsEmptyElement)
                {
                    reader.Read();
                    attribute.AttributeValues.Add(string.Empty);
                }
                else
                {
                    attribute.AttributeValues.Add(ReadAttributeValue(reader, attribute));
                }
            }

            if (attribute.AttributeValues.Count == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ID4212)));
            }

            reader.MoveToContent();
            reader.ReadEndElement();

            return attribute;
        }
        /// <summary>
        /// This method gets called when a special type of SamlAttribute is detected. The SamlAttribute passed in wraps a SamlAttribute 
        /// that contains a collection of AttributeValues, each of which are mapped to a claim.  All of the claims will be returned
        /// in an ClaimsIdentity with the specified issuer.
        /// </summary>
        /// <param name="attribute">The SamlAttribute to be processed.</param>
        /// <param name="subject">The identity that should be modified to reflect the SamlAttribute.</param>
        /// <param name="issuer">Issuer Identity.</param>
        /// <exception cref="InvalidOperationException">Will be thrown if the SamlAttribute does not contain any valid SamlAttributeValues.</exception>
        protected virtual void SetDelegateFromAttribute(SamlAttribute attribute, ClaimsIdentity subject, string issuer)
        {
            // bail here nothing to add.
            if (subject == null || attribute == null || attribute.AttributeValues == null || attribute.AttributeValues.Count < 1)
            {
                return;
            }

            Collection<Claim> claims = new Collection<Claim>();
            SamlAttribute actingAsAttribute = null;

            foreach (string attributeValue in attribute.AttributeValues)
            {
                if (attributeValue != null && attributeValue.Length > 0)
                {

                    using (XmlDictionaryReader xmlReader = XmlDictionaryReader.CreateTextReader(Encoding.UTF8.GetBytes(attributeValue), XmlDictionaryReaderQuotas.Max))
                    {
                        xmlReader.MoveToContent();
                        xmlReader.ReadStartElement(Actor);

                        while (xmlReader.IsStartElement(Attribute))
                        {
                            SamlAttribute innerAttribute = ReadAttribute(xmlReader);
                            if (innerAttribute != null)
                            {
                                string claimType = string.IsNullOrEmpty(innerAttribute.Namespace) ? innerAttribute.Name : innerAttribute.Namespace + "/" + innerAttribute.Name;
                                if (claimType == ClaimTypes.Actor)
                                {
                                    // In this case we have two delegates acting as an identity, we do not allow this
                                    if (actingAsAttribute != null)
                                    {
                                        throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4034));
                                    }

                                    actingAsAttribute = innerAttribute;
                                }
                                else
                                {
                                    string claimValueType = ClaimValueTypes.String;
                                    string originalIssuer = null;
                                    SamlAttribute SamlAttribute = innerAttribute as SamlAttribute;
                                    if (SamlAttribute != null)
                                    {
                                        claimValueType = SamlAttribute.AttributeValueXsiType;
                                        originalIssuer = SamlAttribute.OriginalIssuer;
                                    }
                                    for (int k = 0; k < innerAttribute.AttributeValues.Count; ++k)
                                    {
                                        Claim claim = null;
                                        if (string.IsNullOrEmpty(originalIssuer))
                                        {
                                            claim = new Claim(claimType, innerAttribute.AttributeValues[k], claimValueType, issuer);
                                        }
                                        else
                                        {
                                            claim = new Claim(claimType, innerAttribute.AttributeValues[k], claimValueType, issuer, originalIssuer);
                                        }
                                        claims.Add(claim);
                                    }
                                }
                            }
                        }

                        xmlReader.ReadEndElement(); // Actor
                    }
                }
            }

            subject.Actor = new ClaimsIdentity(claims, AuthenticationTypes.Federation);

            SetDelegateFromAttribute(actingAsAttribute, subject.Actor, issuer);
        }
Ejemplo n.º 15
0
        public virtual SamlAttribute LoadAttribute(XmlDictionaryReader reader, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            // We will load all attributes as string values.
            SamlAttribute attribute = new SamlAttribute();
            attribute.ReadXml(reader, this, keyInfoSerializer, outOfBandTokenResolver);

            return attribute;
        }
Ejemplo n.º 16
0
		public void WriteXmlValid ()
		{
			SamlAssertion a = new SamlAssertion ();
			SamlSubject subject = new SamlSubject (
				SamlConstants.UserNameNamespace,
				"urn:myqualifier",
				"myname");
			SamlAttribute attr = new SamlAttribute (Claim.CreateNameClaim ("myname"));
			SamlAttributeStatement statement =
				new SamlAttributeStatement (subject, new SamlAttribute [] {attr});
			a.Advice = new SamlAdvice (new string [] {"urn:testadvice1"});
			DateTime notBefore = DateTime.SpecifyKind (new DateTime (2000, 1, 1), DateTimeKind.Utc);
			DateTime notOnAfter = DateTime.SpecifyKind (new DateTime (2006, 1, 1), DateTimeKind.Utc);
			a.Conditions = new SamlConditions (notBefore, notOnAfter);
			a.Statements.Add (statement);
			a.Issuer = "my_hero";
			StringWriter sw = new StringWriter ();
			string id = a.AssertionId;
			DateTime instant = a.IssueInstant;
			using (XmlDictionaryWriter dw = CreateWriter (sw)) {
				a.WriteXml (dw, new SamlSerializer (), null);
			}
			string expected = String.Format ("<?xml version=\"1.0\" encoding=\"utf-16\"?><saml:Assertion MajorVersion=\"1\" MinorVersion=\"1\" AssertionID=\"{0}\" Issuer=\"my_hero\" IssueInstant=\"{1}\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\"><saml:Conditions NotBefore=\"{3}\" NotOnOrAfter=\"{4}\" /><saml:Advice><saml:AssertionIDReference>urn:testadvice1</saml:AssertionIDReference></saml:Advice><saml:AttributeStatement><saml:Subject><saml:NameIdentifier Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName\" NameQualifier=\"urn:myqualifier\">myname</saml:NameIdentifier></saml:Subject><saml:Attribute AttributeName=\"name\" AttributeNamespace=\"{2}\"><saml:AttributeValue>myname</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion>",
				id,
				instant.ToString ("yyyy-MM-ddTHH:mm:ss.fff'Z'", CultureInfo.InvariantCulture),
				"http://schemas.xmlsoap.org/ws/2005/05/identity/claims",
				notBefore.ToString ("yyyy-MM-ddTHH:mm:ss.fff'Z'", CultureInfo.InvariantCulture),
				notOnAfter.ToString ("yyyy-MM-ddTHH:mm:ss.fff'Z'", CultureInfo.InvariantCulture));
			Assert.AreEqual (expected, sw.ToString ());
		}