コード例 #1
0
        public static SecurityToken MakeBootstrapSecurityToken()
        {
            Saml2NameIdentifier identifier = new Saml2NameIdentifier("http://localhost/Echo");

            Saml2Assertion assertion = new Saml2Assertion(identifier);

            assertion.Issuer = new Saml2NameIdentifier("idp1.test.oio.dk");
            assertion.Subject = new Saml2Subject(new Saml2NameIdentifier("Casper", new Uri("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified")));
            Saml2Attribute atribute = new Saml2Attribute("dk:gov:saml:attribute:AssuranceLevel", "2");
            atribute.NameFormat = new Uri("urn:oasis:names:tc:SAML:2.0:attrname-format:basic");

            assertion.Statements.Add(new Saml2AttributeStatement(atribute));
            return new Saml2SecurityToken(assertion);
        }
コード例 #2
0
 //public CustomSaml2SecurityTokenHandler(SecurityTokenHandlerConfiguration configuration)
 //{
 //    SecurityTokenHandlerConfiguration handlerConfig = configuration ?? new SecurityTokenHandlerConfiguration
 //    {
 //        AudienceRestriction = {AudienceMode = AudienceUriMode.Never},
 //        CertificateValidationMode = X509CertificateValidationMode.None,
 //        RevocationMode = X509RevocationMode.NoCheck,
 //        MaxClockSkew = new TimeSpan(50000000),
 //        CertificateValidator = X509CertificateValidator.None
 //    };
 //    Configuration = handlerConfig;
 //}
 //public CustomSaml2SecurityTokenHandler()
 //    : this(null)
 //{
 //}
 protected override void WriteAttributeValue(XmlWriter writer, string value, Saml2Attribute attribute)
 {
     var sb = new StringBuilder("<a>");
     sb.Append(value);
     sb.Append("</a>");
     byte[] rawValue = new UTF8Encoding().GetBytes(sb.ToString());
     using (
         XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(rawValue,
             XmlDictionaryReaderQuotas.Max))
     {
         reader.ReadStartElement("a");
         while (reader.NodeType != XmlNodeType.EndElement ||
                (reader.NodeType == XmlNodeType.EndElement && reader.Name != "a"))
         {
             writer.WriteNode(reader, false);
         }
         reader.ReadEndElement();
         reader.Close();
     }
 }
コード例 #3
0
        /// <summary>
        /// Writes the saml:Attribute value.
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2Attribute"/>.</param>
        /// <param name="value">The value of the attribute being serialized.</param>
        /// <param name="attribute">The <see cref="Saml2Attribute"/> to serialize.</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, Saml2Attribute attribute)
        {
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            writer.WriteString(value);
        }
コード例 #4
0
        /// <summary>
        /// Writes the &lt;saml:Attribute> element.
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2Attribute"/>.</param>
        /// <param name="data">The <see cref="Saml2Attribute"/> to serialize.</param>
        protected virtual void WriteAttribute(XmlWriter writer, Saml2Attribute data)
        {
            if (null == writer)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

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

            // <Attribute>
            writer.WriteStartElement(Saml2Constants.Elements.Attribute, Saml2Constants.Namespace);

            // @Name - required
            writer.WriteAttributeString(Saml2Constants.Attributes.Name, data.Name);

            // @NameFormat - optional
            if (null != data.NameFormat)
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.NameFormat, data.NameFormat.AbsoluteUri);
            }

            // @FriendlyName - optional
            if (null != data.FriendlyName)
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.FriendlyName, data.FriendlyName);
            }

            // @OriginalIssuer - optional
            if (null != data.OriginalIssuer)
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.OriginalIssuer, ClaimType2009Namespace, data.OriginalIssuer);
            }

            string xsiTypePrefix = null;
            string xsiTypeSuffix = null;
            if (!StringComparer.Ordinal.Equals(data.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 = data.AttributeValueXsiType.IndexOf('#');
                xsiTypePrefix = data.AttributeValueXsiType.Substring(0, indexOfHash);
                xsiTypeSuffix = data.AttributeValueXsiType.Substring(indexOfHash + 1);
            }

            // <AttributeValue> 0-OO (nillable)
            foreach (string value in data.Values)
            {
                writer.WriteStartElement(Saml2Constants.Elements.AttributeValue, Saml2Constants.Namespace);

                if (null == value)
                {
                    writer.WriteAttributeString("nil", XmlSchema.InstanceNamespace, XmlConvert.ToString(true));
                }
                else if (value.Length > 0)
                {
                    if ((xsiTypePrefix != null) && (xsiTypeSuffix != null))
                    {
                        writer.WriteAttributeString("xmlns", ProductConstants.ClaimValueTypeSerializationPrefix, null, xsiTypePrefix);
                        writer.WriteAttributeString("type", XmlSchema.InstanceNamespace, String.Concat(ProductConstants.ClaimValueTypeSerializationPrefixWithColon, xsiTypeSuffix));
                    }

                    this.WriteAttributeValue(writer, value, data);
                }

                writer.WriteEndElement();
            }

            // </Attribute>
            writer.WriteEndElement();
        }
コード例 #5
0
        /// <summary>
        /// Reads an attribute value.
        /// </summary>
        /// <param name="reader">A <see cref="XmlReader"/> positioned at a <see cref="Saml2Attribute"/>.</param>
        /// <param name="attribute">The <see cref="Saml2Attribute"/>.</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, Saml2Attribute 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, Saml2Constants.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;
        }
コード例 #6
0
        /// <summary>
        /// Reads the &lt;saml:Attribute> element.
        /// </summary>
        /// <remarks>
        /// The default implementation requires that the content of the 
        /// Attribute element be a simple string. To handle complex content
        /// or content of declared simple types other than xs:string, override
        /// this method.
        /// </remarks>
        /// <param name="reader">An <see cref="XmlReader"/> positioned at a <see cref="Saml2Attribute"/> element.</param>
        /// <returns>A <see cref="Saml2Attribute"/> instance.</returns>
        protected virtual Saml2Attribute ReadAttribute(XmlReader reader)
        {
            if (null == reader)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            // throw if wrong element
            if (!reader.IsStartElement(Saml2Constants.Elements.Attribute, Saml2Constants.Namespace))
            {
                reader.ReadStartElement(Saml2Constants.Elements.Attribute, Saml2Constants.Namespace);
            }

            try
            {
                Saml2Attribute attribute;
                bool isEmpty = reader.IsEmptyElement;

                // @attributes
                string value;

                // @xsi:type 
                XmlUtil.ValidateXsiType(reader, Saml2Constants.Types.AttributeType, Saml2Constants.Namespace);

                // @Name - required
                value = reader.GetAttribute(Saml2Constants.Attributes.Name);
                if (string.IsNullOrEmpty(value))
                {
                    throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID0001, Saml2Constants.Attributes.Name, Saml2Constants.Elements.Attribute));
                }

                attribute = new Saml2Attribute(value);

                // @NameFormat - optional
                value = reader.GetAttribute(Saml2Constants.Attributes.NameFormat);
                if (!string.IsNullOrEmpty(value))
                {
                    if (!UriUtil.CanCreateValidUri(value, UriKind.Absolute))
                    {
                        throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID0011, Saml2Constants.Attributes.Namespace, Saml2Constants.Elements.Action));
                    }

                    attribute.NameFormat = new Uri(value);
                }

                // @FriendlyName - optional
                attribute.FriendlyName = reader.GetAttribute(Saml2Constants.Attributes.FriendlyName);

                // @OriginalIssuer - optional.
                // 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(Saml2Constants.Attributes.OriginalIssuer, ClaimType2009Namespace);

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

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

                attribute.OriginalIssuer = originalIssuer;

                // content
                reader.Read();
                if (!isEmpty)
                {
                    while (reader.IsStartElement(Saml2Constants.Elements.AttributeValue, Saml2Constants.Namespace))
                    {
                        bool isEmptyValue = reader.IsEmptyElement;
                        bool isNil = XmlUtil.IsNil(reader);

                        // 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.
                        // For attributeValueXsiTypeSuffix, we want the portion after the local prefix in "some-non-empty-local-prefix:some-non-empty-string"
                        // "some-non-empty-local-prefix:some-non-empty-string" case
                        string attributeValueXsiTypePrefix = null;
                        string attributeValueXsiTypeSuffix = null;
                        string attributeValueXsiTypeSuffixWithLocalPrefix = reader.GetAttribute("type", XmlSchema.InstanceNamespace);
                        if (!string.IsNullOrEmpty(attributeValueXsiTypeSuffixWithLocalPrefix))
                        {
                            // "some-non-empty-string" case
                            if (attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) == -1)
                            {
                                attributeValueXsiTypePrefix = reader.LookupNamespace(String.Empty);
                                attributeValueXsiTypeSuffix = attributeValueXsiTypeSuffixWithLocalPrefix;
                            }
                            else if (attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) > 0 &&
                                      attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) < attributeValueXsiTypeSuffixWithLocalPrefix.Length - 1)
                            {
                                string localPrefix = attributeValueXsiTypeSuffixWithLocalPrefix.Substring(0, attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal));
                                attributeValueXsiTypePrefix = reader.LookupNamespace(localPrefix);
                                attributeValueXsiTypeSuffix = attributeValueXsiTypeSuffixWithLocalPrefix.Substring(attributeValueXsiTypeSuffixWithLocalPrefix.IndexOf(":", StringComparison.Ordinal) + 1);
                            }
                        }

                        if (attributeValueXsiTypePrefix != null && attributeValueXsiTypeSuffix != null)
                        {
                            attribute.AttributeValueXsiType = String.Concat(attributeValueXsiTypePrefix, "#", attributeValueXsiTypeSuffix);
                        }

                        if (isNil)
                        {
                            reader.Read();
                            if (!isEmptyValue)
                            {
                                reader.ReadEndElement();
                            }

                            attribute.Values.Add(null);
                        }
                        else if (isEmptyValue)
                        {
                            reader.Read();
                            attribute.Values.Add(string.Empty);
                        }
                        else
                        {
                            attribute.Values.Add(this.ReadAttributeValue(reader, attribute));
                        }
                    }

                    reader.ReadEndElement();
                }

                return attribute;
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                Exception wrapped = TryWrapReadException(reader, e);
                if (null == wrapped)
                {
                    throw;
                }
                else
                {
                    throw wrapped;
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// This method gets called when a special type of Saml2Attribute is detected. The Saml2Attribute passed in 
        /// wraps a Saml2Attribute that contains a collection of AttributeValues, each of which will get mapped to a 
        /// claim.  All of the claims will be returned in an ClaimsIdentity with the specified issuer.
        /// </summary>
        /// <param name="attribute">The <see cref="Saml2Attribute"/> to use.</param>
        /// <param name="subject">The <see cref="ClaimsIdentity"/> that is the subject of this token.</param>
        /// <param name="issuer">The issuer of the claim.</param>
        /// <exception cref="InvalidOperationException">Will be thrown if the Saml2Attribute does not contain any 
        /// valid Saml2AttributeValues.
        /// </exception>
        protected virtual void SetDelegateFromAttribute(Saml2Attribute attribute, ClaimsIdentity subject, string issuer)
        {
            // bail here; nothing to add.
            if (subject == null || attribute == null || attribute.Values == null || attribute.Values.Count < 1)
            {
                return;
            }

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

            foreach (string attributeValue in attribute.Values)
            {
                if (attributeValue != null)
                {
                    using (XmlDictionaryReader dicReader = XmlDictionaryReader.CreateTextReader(Encoding.UTF8.GetBytes(attributeValue), XmlDictionaryReaderQuotas.Max))
                    {
                        dicReader.MoveToContent();
                        dicReader.ReadStartElement(Actor);

                        while (dicReader.IsStartElement(Attribute))
                        {
                            Saml2Attribute innerAttribute = this.ReadAttribute(dicReader);
                            if (innerAttribute != null)
                            {
                                if (innerAttribute.Name == 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.ID4218));
                                    }

                                    actingAsAttribute = innerAttribute;
                                }
                                else
                                {
                                    string originalIssuer = innerAttribute.OriginalIssuer;
                                    for (int k = 0; k < innerAttribute.Values.Count; ++k)
                                    {
                                        Claim claim = null;
                                        if (string.IsNullOrEmpty(originalIssuer))
                                        {
                                            claim = new Claim(innerAttribute.Name, innerAttribute.Values[k], innerAttribute.AttributeValueXsiType, issuer);
                                        }
                                        else
                                        {
                                            claim = new Claim(innerAttribute.Name, innerAttribute.Values[k], innerAttribute.AttributeValueXsiType, issuer, originalIssuer);
                                        }

                                        if (innerAttribute.NameFormat != null)
                                        {
                                            claim.Properties[ClaimProperties.SamlAttributeNameFormat] = innerAttribute.NameFormat.AbsoluteUri;
                                        }

                                        if (innerAttribute.FriendlyName != null)
                                        {
                                            claim.Properties[ClaimProperties.SamlAttributeDisplayName] = innerAttribute.FriendlyName;
                                        }

                                        claims.Add(claim);
                                    }
                                }
                            }
                        }

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

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

            this.SetDelegateFromAttribute(actingAsAttribute, subject.Actor, issuer);
        }
コード例 #8
0
        /// <summary>
        /// Generates a Saml2Attribute from a claim.
        /// </summary>
        /// <param name="claim">The <see cref="Claim"/> from which to generate a <see cref="Saml2Attribute"/>.</param>
        /// <param name="tokenDescriptor">Contains all the information that is used in token issuance.</param>
        /// <returns>A <see cref="Saml2Attribute"/> based on the claim.</returns>
        /// <exception cref="ArgumentNullException">The parameter 'claim' is null.</exception>
        protected virtual Saml2Attribute CreateAttribute(Claim claim, SecurityTokenDescriptor tokenDescriptor)
        {
            if (claim == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim");
            }

            Saml2Attribute attribute = new Saml2Attribute(claim.Type, claim.Value);
            if (!StringComparer.Ordinal.Equals(ClaimsIdentity.DefaultIssuer, claim.OriginalIssuer))
            {
                attribute.OriginalIssuer = claim.OriginalIssuer;
            }

            attribute.AttributeValueXsiType = claim.ValueType;

            if (claim.Properties.ContainsKey(ClaimProperties.SamlAttributeNameFormat))
            {
                string nameFormat = claim.Properties[ClaimProperties.SamlAttributeNameFormat];
                if (!UriUtil.CanCreateValidUri(nameFormat, UriKind.Absolute))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("nameFormat", SR.GetString(SR.ID0013));
                }

                attribute.NameFormat = new Uri(nameFormat);
            }

            if (claim.Properties.ContainsKey(ClaimProperties.SamlAttributeDisplayName))
            {
                attribute.FriendlyName = claim.Properties[ClaimProperties.SamlAttributeDisplayName];
            }

            return attribute;
        }
コード例 #9
0
        private static void CreateIdentityProviderMetadata(SamlIdpData idpData, string fileName, Encoding encoding)
        {
            if ( string.IsNullOrEmpty(idpData.SigninCertificateCn))
                throw new ApplicationException("no CN for a Certificate supplied");

            string signingCertificateSubjectName = idpData.SigninCertificateCn;

            Constants.NameIdType nidFmt = idpData.NameIdType;

            MetadataSerializer serializer = new MetadataSerializer();
            IdentityProviderSingleSignOnDescriptor item = new IdentityProviderSingleSignOnDescriptor();

            EntityDescriptor metadata = new EntityDescriptor();
            metadata.EntityId = new EntityId(idpData.EntityId);

            X509Certificate2 certificate = CertificateHelper.RetrieveCertificate(signingCertificateSubjectName);
            KeyDescriptor descriptor = new KeyDescriptor(
                new SecurityKeyIdentifier(
                    new SecurityKeyIdentifierClause[]
                    {
                        new X509SecurityToken(certificate).CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>()
                    }));

            descriptor.Use = KeyType.Signing;
            item.Keys.Add(descriptor);

            //using 2.0
            if (Constants.NameIdType.Saml20 == nidFmt)
                item.NameIdentifierFormats.Add(Saml2Constants.NameIdentifierFormats.Transient);

            //using 1.1
            if (Constants.NameIdType.Saml11 == nidFmt)
                item.NameIdentifierFormats.Add(Saml2Constants.NameIdentifierFormats.Unspecified);

            foreach (var attributeName in idpData.AttributeNames)
            {
                Saml2Attribute at1 = new Saml2Attribute(attributeName.Name)
                {
                    NameFormat = new Uri(Constants.Saml20AttributeNameFormat)
                };
                item.SupportedAttributes.Add(at1);
            }

            item.ProtocolsSupported.Add(new Uri(Constants.Saml20Protocol));
            item.SingleSignOnServices.Add(new ProtocolEndpoint(new Uri(idpData.BindingType), new Uri(idpData.BindingLocation)));

            metadata.RoleDescriptors.Add(item);

            metadata.Contacts.Add(new ContactPerson(ContactType.Technical)
            {
                Company = idpData.MainContact.Company,
                GivenName = idpData.MainContact.GivenName,
                Surname = idpData.MainContact.SurName,
                EmailAddresses = { idpData.MainContact.Email },
                TelephoneNumbers = { idpData.MainContact.Phone }
            });

            XmlTextWriter writer = new XmlTextWriter(fileName, encoding);
            serializer.WriteMetadata(writer, metadata);
            writer.Close();
        }
コード例 #10
0
        protected override void WriteAttribute(XmlWriter writer, Saml2Attribute data)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            // Do not serialize the actor attribute since the Condition/Delegate element has the delegate
            if ("http://schemas.xmlsoap.org/ws/2009/09/identity/claims/actor" == data.Name)
            {
                return;
            }
            
            writer.WriteStartElement("Attribute", "urn:oasis:names:tc:SAML:2.0:assertion");
            writer.WriteAttributeString("Name", data.Name);
            
            if (null != data.NameFormat)
            {
                writer.WriteAttributeString("NameFormat", data.NameFormat.AbsoluteUri);
            }

            if (data.FriendlyName != null)
            {
                writer.WriteAttributeString("FriendlyName", data.FriendlyName);
            }

            if (data.OriginalIssuer != null)
            {
                writer.WriteAttributeString("OriginalIssuer", "http://schemas.xmlsoap.org/ws/2009/09/identity/claims", data.OriginalIssuer);
            }

            string xmlSchemaNamespace = null;
            string xmlSchemaType = null;
            if (!StringComparer.Ordinal.Equals(data.AttributeValueXsiType, "http://www.w3.org/2001/XMLSchema#string"))
            {
                int index = data.AttributeValueXsiType.IndexOf('#');
                xmlSchemaNamespace = data.AttributeValueXsiType.Substring(0, index);
                xmlSchemaType = data.AttributeValueXsiType.Substring(index + 1);
            }

            foreach (string attributeValue in data.Values)
            {
                writer.WriteStartElement("AttributeValue", "urn:oasis:names:tc:SAML:2.0:assertion");
                if (attributeValue == null)
                {
                    writer.WriteAttributeString("nil", "http://www.w3.org/2001/XMLSchema-instance", XmlConvert.ToString(true));
                }
                else if (attributeValue.Length > 0)
                {
                    if ((xmlSchemaNamespace != null) && (xmlSchemaType != null))
                    {
                        writer.WriteAttributeString("xmlns", "tn", null, xmlSchemaNamespace);
                        writer.WriteAttributeString("type", "http://www.w3.org/2001/XMLSchema-instance", "tn:" + xmlSchemaType);
                    }
                    else
                    {
                        // GFIPM S2S Appendix A: GFIPM-Specific SAML Assertion Format Rules
                        // Sect 19. <AttributeValue> attributes
                        writer.WriteAttributeString("xmlns", "xs", null, "http://www.w3.org/2001/XMLSchema");
                        writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
                        writer.WriteAttributeString("xsi", "type", "http://www.w3.org/2001/XMLSchema-instance", "xs:string");
                    }
                    this.WriteAttributeValue(writer, attributeValue, data);
                }
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
コード例 #11
0
 /// <summary>
 /// Creates an instance of Saml2AttributeStatement.
 /// </summary>
 /// <param name="attribute">The <see cref="Saml2Attribute"/> contained in this statement.</param>
 public Saml2AttributeStatement(Saml2Attribute attribute)
     : this(new Saml2Attribute[] { attribute })
 {
 }
コード例 #12
0
 protected override string ReadAttributeValue(XmlReader reader, Saml2Attribute attribute)
 {
     if (attribute.Name != null)
     {
         return base.ReadAttributeValue(reader, attribute);
     }
     return "empty";
 }