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; }
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); }
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); }
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); }
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); }
/// <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 <Issuer> and <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 <Issuer> and <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 <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 <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; }