Пример #1
0
        private static Saml2NameIdentifier ProcessLogoutNameIdentifier(Claim claim)
        {
            var fields = DelimitedString.Split(claim.Value);

            var saml2NameIdentifier = new Saml2NameIdentifier(fields[4]);

            if (!string.IsNullOrEmpty(fields[0]))
            {
                saml2NameIdentifier.NameQualifier = fields[0];
            }
            if (!string.IsNullOrEmpty(fields[1]))
            {
                saml2NameIdentifier.SPNameQualifier = fields[1];
            }
            if (!string.IsNullOrEmpty(fields[2]))
            {
                saml2NameIdentifier.Format = new Uri(fields[2]);
            }
            if (!string.IsNullOrEmpty(fields[3]))
            {
                saml2NameIdentifier.SPProvidedId = fields[3];
            }

            return saml2NameIdentifier;
        }
        /// <summary>
        /// Creates an instance of a Saml2Assertion.
        /// </summary>
        /// <param name="issuer">Issuer of the assertion.</param>
        public Saml2Assertion(Saml2NameIdentifier issuer)
        {
            if (issuer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuer");
            }

            this.issuer = issuer;
        }
        /// <summary>
        /// Creates an instance of a Saml2Assertion.
        /// </summary>
        /// <param name="issuer">Issuer of the assertion.</param>
        public Saml2Assertion(Saml2NameIdentifier issuer)
        {
            if (issuer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuer");
            }

            this.issuer = issuer;
        }
Пример #4
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_NameOnly()
        {
            var claim = new Claim(ClaimTypes.NameIdentifier, "NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId");

            actual.ShouldBeEquivalentTo(expected);
        }
        public Saml2LogoutRequest()
        {
            NotOnOrAfter = DateTime.UtcNow.AddMinutes(10);

            var identity = ClaimsPrincipal.Current.Identities.First();
            if (identity.IsAuthenticated)
            {
                NameId = new Saml2NameIdentifier(ReadClaimValue(identity, Saml2ClaimTypes.NameId), new Uri(ReadClaimValue(identity, Saml2ClaimTypes.NameIdFormat)));
                SessionIndex = ReadClaimValue(identity, Saml2ClaimTypes.SessionIndex);
            }           
        }
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_NameIdFormat()
        {
            var claim = new Claim(AuthServicesClaimTypes.LogoutNameIdentifier, ",,urn:foo,,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                Format = new Uri("urn:foo")
            };

            actual.ShouldBeEquivalentTo(expected);
        }
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_SPNameQualifier()
        {
            var claim = new Claim(AuthServicesClaimTypes.LogoutNameIdentifier, ",qualifier,,,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                SPNameQualifier = "qualifier"
            };

            actual.ShouldBeEquivalentTo(expected);
        }
        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);
        }
Пример #9
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_SPNameQualifier()
        {
            var claim = new Claim(ClaimTypes.NameIdentifier, "NameId");
            claim.Properties[ClaimProperties.SamlNameIdentifierSPNameQualifier] = "qualifier";

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                SPNameQualifier = "qualifier"
            };

            actual.ShouldBeEquivalentTo(expected);
        }
Пример #10
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_NameIdFormat()
        {
            var claim = new Claim(ClaimTypes.NameIdentifier, "NameId");
            claim.Properties[ClaimProperties.SamlNameIdentifierFormat] = "urn:foo";

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                Format = new Uri("urn:foo")
            };

            actual.ShouldBeEquivalentTo(expected);
        }
Пример #11
0
        private static Saml2NameIdentifier ProcessNameIdentifier(Claim claim)
        {
            var saml2NameIdentifier = new Saml2NameIdentifier(claim.Value);

            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierFormat,
                value => saml2NameIdentifier.Format = new Uri(value));
            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierNameQualifier,
                value => saml2NameIdentifier.NameQualifier = value);
            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierSPNameQualifier,
                value => saml2NameIdentifier.SPNameQualifier = value);
            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierSPProvidedId,
                value => saml2NameIdentifier.SPProvidedId = value);

            return saml2NameIdentifier;
        }
        public void IdentityProvider_CreateLogoutRequest()
        {
            var options = StubFactory.CreateOptions();
            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate()
            {
                Certificate = SignedXmlHelper.TestCert
            });

            var subject = options.IdentityProviders[0];

            var logoutNameIdClaim = new Claim(
                AuthServicesClaimTypes.LogoutNameIdentifier, ",,urn:nameIdFormat,,NameId", null, subject.EntityId.Id);

            var user = new ClaimsPrincipal(new ClaimsIdentity(
                new Claim[]
                {
                    logoutNameIdClaim,
                    new Claim(AuthServicesClaimTypes.SessionIndex, "SessionId", null, subject.EntityId.Id)
                }, "Federation"));

            // Grab a datetime both before and after creation to handle case
            // when the second part is changed during excecution of the test.
            // We're assuming that the creation does not take more than a
            // second, so two values will do.
            var beforeTime = DateTime.UtcNow.ToSaml2DateTimeString();
            var actual = subject.CreateLogoutRequest(user);
            var aftertime = DateTime.UtcNow.ToSaml2DateTimeString();

            actual.Issuer.Id.Should().Be(options.SPOptions.EntityId.Id);
            actual.Id.Value.Should().NotBeEmpty();
            actual.IssueInstant.Should().Match(i => i == beforeTime || i == aftertime);
            actual.SessionIndex.Should().Be("SessionId");
            actual.SigningCertificate.Thumbprint.Should().Be(SignedXmlHelper.TestCert.Thumbprint);

            var expectedNameId = new Saml2NameIdentifier("NameId")
            {
                Format = new Uri("urn:nameIdFormat")
            };
            actual.NameId.ShouldBeEquivalentTo(expectedNameId);
        }
Пример #13
0
 /// <summary>
 /// Initializes an instance of <see cref="Saml2Subject"/> from a <see cref="Saml2NameIdentifier"/>.
 /// </summary>
 /// <param name="nameId">The <see cref="Saml2NameIdentifier"/> to use for initialization.</param>
 public Saml2Subject(Saml2NameIdentifier nameId)
 {
     this.nameId = nameId;
 }
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_SPProvidedId()
        {
            var claim = new Claim(AuthServicesClaimTypes.LogoutNameIdentifier, ",,,spId,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                SPProvidedId = "spId"
            };

            actual.ShouldBeEquivalentTo(expected);
        }
        /// <summary>
        /// Both &lt;Issuer> and &lt;NameID> are of NameIDType. This method writes
        /// the content of either one of those elements. 
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2NameIdentifier"/>.</param>
        /// <param name="data">The <see cref="Saml2NameIdentifier"/> to serialize.</param>
        protected virtual void WriteNameIdType(XmlWriter writer, Saml2NameIdentifier data)
        {
            // @Format - optional
            if (null != data.Format)
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.Format, data.Format.AbsoluteUri);
            }

            // @NameQualifier - optional
            if (!string.IsNullOrEmpty(data.NameQualifier))
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.NameQualifier, data.NameQualifier);
            }

            // @SPNameQualifier - optional
            if (!string.IsNullOrEmpty(data.SPNameQualifier))
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.SPNameQualifier, data.SPNameQualifier);
            }

            // @SPProvidedId - optional
            if (!string.IsNullOrEmpty(data.SPProvidedId))
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.SPProvidedID, data.SPProvidedId);
            }

            // Content is string
            writer.WriteString(data.Value);
        }
        /// <summary>
        /// Both &lt;Issuer> and &lt;NameID> are of NameIDType. This method reads
        /// the content of either one of those elements. 
        /// </summary>
        /// <param name="reader">A <see cref="XmlReader"/> positioned at a <see cref="Saml2NameIdentifier"/> element.</param>
        /// <returns>An instance of <see cref="Saml2NameIdentifier"/></returns>
        protected virtual Saml2NameIdentifier ReadNameIdType(XmlReader reader)
        {
            try
            {
                reader.MoveToContent();

                Saml2NameIdentifier nameIdentifier = new Saml2NameIdentifier("__TemporaryName__");

                // @attributes
                string value;

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

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

                    nameIdentifier.Format = new Uri(value);
                }

                // @NameQualifier - optional
                value = reader.GetAttribute(Saml2Constants.Attributes.NameQualifier);
                if (!string.IsNullOrEmpty(value))
                {
                    nameIdentifier.NameQualifier = value;
                }

                // @SPNameQualifier - optional
                value = reader.GetAttribute(Saml2Constants.Attributes.SPNameQualifier);
                if (!string.IsNullOrEmpty(value))
                {
                    nameIdentifier.SPNameQualifier = value;
                }

                // @SPProvidedID - optional
                value = reader.GetAttribute(Saml2Constants.Attributes.SPProvidedID);
                if (!string.IsNullOrEmpty(value))
                {
                    nameIdentifier.SPProvidedId = value;
                }

                // Content is string
                nameIdentifier.Value = reader.ReadElementString();

                // According to section 8.3.6, if the name identifier format is of type 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
                // the name identifier value must be a uri and name qualifier, spname qualifier, and spproded id must be omitted.
                if (nameIdentifier.Format != null &&
                    StringComparer.Ordinal.Equals(nameIdentifier.Format.AbsoluteUri, Saml2Constants.NameIdentifierFormats.Entity.AbsoluteUri))
                {
                    if (!UriUtil.CanCreateValidUri(nameIdentifier.Value, UriKind.Absolute))
                    {
                        throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID4262, nameIdentifier.Value, Saml2Constants.NameIdentifierFormats.Entity.AbsoluteUri));
                    }

                    if (!string.IsNullOrEmpty(nameIdentifier.NameQualifier)
                        || !string.IsNullOrEmpty(nameIdentifier.SPNameQualifier)
                        || !string.IsNullOrEmpty(nameIdentifier.SPProvidedId))
                    {
                        throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID4263, nameIdentifier.Value, Saml2Constants.NameIdentifierFormats.Entity.AbsoluteUri));
                    }
                }

                return nameIdentifier;
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                Exception wrapped = TryWrapReadException(reader, e);
                if (null == wrapped)
                {
                    throw;
                }
                else
                {
                    throw wrapped;
                }
            }
        }
        /// <summary>
        /// Writes the &lt;saml:NameID> element.
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2NameIdentifier"/>.</param>
        /// <param name="data">The <see cref="Saml2NameIdentifier"/> to serialize.</param>
        /// <exception cref="ArgumentNullException">The input parameter 'writer' or 'data' is null.</exception>
        /// <exception cref="CryptographicException">Saml2NameIdentifier encrypting credentials must have a Symmetric Key specified.</exception>
        protected virtual void WriteNameId(XmlWriter writer, Saml2NameIdentifier data)
        {
            if (null == writer)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

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

            // If there are encrypting credentials, then we need to encrypt the name identifier
            if (data.EncryptingCredentials != null)
            {
                EncryptingCredentials encryptingCredentials = data.EncryptingCredentials;

                // Get the encryption key, which must be symmetric
                SymmetricSecurityKey encryptingKey = encryptingCredentials.SecurityKey as SymmetricSecurityKey;
                if (encryptingKey == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CryptographicException(SR.GetString(SR.ID3284)));
                }

                MemoryStream plaintextStream = null;
                try
                {
                    // Serialize an encrypted name ID
                    plaintextStream = new MemoryStream();

                    using (XmlWriter plaintextWriter = XmlDictionaryWriter.CreateTextWriter(plaintextStream, Encoding.UTF8, false))
                    {
                        plaintextWriter.WriteStartElement(Saml2Constants.Elements.NameID, Saml2Constants.Namespace);
                        this.WriteNameIdType(plaintextWriter, data);
                        plaintextWriter.WriteEndElement();
                    }

                    EncryptedDataElement encryptedData = new EncryptedDataElement();
                    encryptedData.Type = XmlEncryptionConstants.EncryptedDataTypes.Element;
                    encryptedData.Algorithm = encryptingCredentials.Algorithm;
                    encryptedData.KeyIdentifier = encryptingCredentials.SecurityKeyIdentifier;

                    // Perform encryption
                    SymmetricAlgorithm symmetricAlgorithm = encryptingKey.GetSymmetricAlgorithm(encryptingCredentials.Algorithm);
                    encryptedData.Encrypt(symmetricAlgorithm, plaintextStream.GetBuffer(), 0, (int)plaintextStream.Length);
                    ((IDisposable)plaintextStream).Dispose();

                    writer.WriteStartElement(Saml2Constants.Elements.EncryptedID, Saml2Constants.Namespace);
                    encryptedData.WriteXml(writer, this.KeyInfoSerializer);

                    foreach (EncryptedKeyIdentifierClause clause in data.ExternalEncryptedKeys)
                    {
                        this.KeyInfoSerializer.WriteKeyIdentifierClause(writer, clause);
                    }

                    writer.WriteEndElement();
                }
                finally
                {
                    if (plaintextStream != null)
                    {
                        plaintextStream.Dispose();
                        plaintextStream = null;
                    }
                }
            }
            else
            {
                writer.WriteStartElement(Saml2Constants.Elements.NameID, Saml2Constants.Namespace);
                this.WriteNameIdType(writer, data);
                writer.WriteEndElement();
            }
        }
        /// <summary>
        /// Writes the &lt;saml:Issuer> element.
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2NameIdentifier"/>.</param>
        /// <param name="data">The <see cref="Saml2NameIdentifier"/> to serialize.</param>
        protected virtual void WriteIssuer(XmlWriter writer, Saml2NameIdentifier data)
        {
            if (null == writer)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

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

            writer.WriteStartElement(Saml2Constants.Elements.Issuer, Saml2Constants.Namespace);
            this.WriteNameIdType(writer, data);
            writer.WriteEndElement();
        }
        /// <summary>
        /// Creates a SAML2 subject of the assertion.
        /// </summary>
        /// <param name="tokenDescriptor">The security token descriptor to create the subject.</param>
        /// <exception cref="ArgumentNullException">Thrown when 'tokenDescriptor' is null.</exception>
        /// <returns>A Saml2Subject.</returns>
        protected virtual Saml2Subject CreateSamlSubject(SecurityTokenDescriptor tokenDescriptor)
        {
            if (null == tokenDescriptor)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenDescriptor");
            }

            Saml2Subject saml2Subject = new Saml2Subject();

            // Look for name identifier claims
            string nameIdentifierClaim = null;
            string nameIdentifierFormat = null;
            string nameIdentifierNameQualifier = null;
            string nameIdentifierSpProviderId = null;
            string nameIdentifierSpNameQualifier = null;

            if (tokenDescriptor.Subject != null && tokenDescriptor.Subject.Claims != null)
            {
                foreach (Claim claim in tokenDescriptor.Subject.Claims)
                {
                    if (claim.Type == ClaimTypes.NameIdentifier)
                    {
                        // Do not allow multiple name identifier claim.
                        if (null != nameIdentifierClaim)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4139)));
                        }

                        nameIdentifierClaim = claim.Value;

                        if (claim.Properties.ContainsKey(ClaimProperties.SamlNameIdentifierFormat))
                        {
                            nameIdentifierFormat = claim.Properties[ClaimProperties.SamlNameIdentifierFormat];
                        }

                        if (claim.Properties.ContainsKey(ClaimProperties.SamlNameIdentifierNameQualifier))
                        {
                            nameIdentifierNameQualifier = claim.Properties[ClaimProperties.SamlNameIdentifierNameQualifier];
                        }

                        if (claim.Properties.ContainsKey(ClaimProperties.SamlNameIdentifierSPNameQualifier))
                        {
                            nameIdentifierSpNameQualifier = claim.Properties[ClaimProperties.SamlNameIdentifierSPNameQualifier];
                        }

                        if (claim.Properties.ContainsKey(ClaimProperties.SamlNameIdentifierSPProvidedId))
                        {
                            nameIdentifierSpProviderId = claim.Properties[ClaimProperties.SamlNameIdentifierSPProvidedId];
                        }
                    }
                }
            }

            if (nameIdentifierClaim != null)
            {
                Saml2NameIdentifier nameIdentifier = new Saml2NameIdentifier(nameIdentifierClaim);

                if (nameIdentifierFormat != null && UriUtil.CanCreateValidUri(nameIdentifierFormat, UriKind.Absolute))
                {
                    nameIdentifier.Format = new Uri(nameIdentifierFormat);
                }

                nameIdentifier.NameQualifier = nameIdentifierNameQualifier;
                nameIdentifier.SPNameQualifier = nameIdentifierSpNameQualifier;
                nameIdentifier.SPProvidedId = nameIdentifierSpProviderId;

                saml2Subject.NameId = nameIdentifier;
            }

            // Add subject confirmation data
            Saml2SubjectConfirmation subjectConfirmation;
            if (null == tokenDescriptor.Proof)
            {
                subjectConfirmation = new Saml2SubjectConfirmation(Saml2Constants.ConfirmationMethods.Bearer);
            }
            else
            {
                subjectConfirmation = new Saml2SubjectConfirmation(Saml2Constants.ConfirmationMethods.HolderOfKey, new Saml2SubjectConfirmationData());
                subjectConfirmation.SubjectConfirmationData.KeyIdentifiers.Add(tokenDescriptor.Proof.KeyIdentifier);
            }

            saml2Subject.SubjectConfirmations.Add(subjectConfirmation);

            return saml2Subject;
        }
        protected override Saml2Subject CreateSamlSubject(SecurityTokenDescriptor tokenDescriptor)
        {
            Saml2SubjectConfirmation confirmation;
            if (tokenDescriptor == null)
            {
                throw new ArgumentNullException("tokenDescriptor");
            }
            Saml2Subject subject = new Saml2Subject();
            string name = null;
            string uriString = null;

            if ((tokenDescriptor.Subject != null) && (tokenDescriptor.Subject.Claims != null))
            {
                foreach (Claim claim in tokenDescriptor.Subject.Claims)
                {
                    if (claim.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")
                    {
                        if (name != null)
                        {
                            throw new InvalidOperationException(
                                "No suitable Saml2NameIdentifier could be created for the SAML2:Subject because more than one Claim of type NameIdentifier was supplied.");
                        }
                        name = claim.Value;
                        if (claim.Properties.ContainsKey("http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"))
                        {
                            uriString = claim.Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"];
                        }                        
                    }
                }
            }
            if (name != null)
            {
                Saml2NameIdentifier identifier = new Saml2NameIdentifier(name);

                if ((uriString != null) && UriUtil.CanCreateValidUri(uriString, UriKind.Absolute))
                {
                    identifier.Format = new Uri(uriString);
                }
                subject.NameId = identifier;
            }

            // IGNORE SAML confirmation and just create the SenderVouches

            // GFIPM S2S 8.8.2.6.c
            confirmation = new Saml2SubjectConfirmation(Saml2Constants.ConfirmationMethods.SenderVouches);

            // SAML V2.0 Condition for Delegation Restriction Version 1.0
            // 2.5 Use of Identifiers Within <saml:SubjectConfirmation>
            string lastDelegateNameId = tokenDescriptor.Subject.Actor.Name;
            confirmation.NameIdentifier = new Saml2NameIdentifier(lastDelegateNameId);

            subject.SubjectConfirmations.Add(confirmation);

            return subject;
        }
 /// <summary>
 /// Initializes an instance of <see cref="Saml2Subject"/> from a <see cref="Saml2NameIdentifier"/>.
 /// </summary>
 /// <param name="nameId">The <see cref="Saml2NameIdentifier"/> to use for initialization.</param>
 public Saml2Subject(Saml2NameIdentifier nameId)
 {
     this.nameId = nameId;
 }