using System; using System.Collections.Generic; using System.Text; using System.ServiceModel.Channels; using System.ServiceModel.Security; using System.Xml; using System.IdentityModel.Tokens; using System.IdentityModel.Claims; using System.Security.Cryptography.X509Certificates; using System.Runtime.Serialization; using System.IdentityModel.Selectors; using System.Configuration; using RST = Microsoft.ServiceModel.Samples.SecurityTokenService.RequestSecurityToken; namespace Microsoft.ServiceModel.Samples.SecurityTokenService { class RequestSecurityTokenResponse : BodyWriter { string context; SecurityKeyIdentifier useKey; string keyType; public RequestSecurityTokenResponse(RST rst) :base(false) { this.context = rst.Context; this.useKey = rst.UseKey; this.keyType = rst.KeyType; } /// /// SAMPLE EXTENSIBILITY TASK: /// /// Returns the SAML attributes to insert into the token /// /// Add your own claims into the token in this method /// /// /// protected List GetTokenAttributes() { List result = new List(); // THIS IS WHERE WE ADD OUR CLAIMS INTO THE SECURITY TOKEN result.Add(new SamlAttribute(new Claim(ClaimTypes.PPID , "7777777", Rights.PossessProperty))); result.Add(new SamlAttribute(new Claim(ClaimTypes.GivenName, "Martin", Rights.PossessProperty))); result.Add(new SamlAttribute(new Claim(ClaimTypes.Surname, "Parry", Rights.PossessProperty))); result.Add(new SamlAttribute(new Claim(ClaimTypes.Email, "martinparry@hotmail.com", Rights.PossessProperty))); return result; } protected override void OnWriteBodyContents(XmlDictionaryWriter writer) { // // Build the contents of the SAML token // // Subject SamlSubject subject = new SamlSubject(); if ( this.useKey != null ) { // Add the key and the Holder-Of-Key confirmation method subject.KeyIdentifier = this.useKey; subject.ConfirmationMethods.Add( SamlConstants.HolderOfKey ); } else { // This is a bearer token subject.ConfirmationMethods.Add( SamlConstants.SenderVouches ); } // Attributes, statements, conditions, and assertions List statements = new List(); List attributes = GetTokenAttributes(); statements.Add(new SamlAuthenticationStatement(subject, Constants.Saml.AuthenticationMethods.Unspecified, DateTime.Now, null, null, null)); statements.Add(new SamlAttributeStatement(subject, attributes)); SamlConditions conditions = new SamlConditions(DateTime.Now, (DateTime.Now + TimeSpan.FromHours(8.0))); SamlAssertion assertion = new SamlAssertion("uuid-" + Guid.NewGuid(), Program.Issuer, DateTime.Now, conditions, null, statements); // Build the signing token SecurityToken signingToken = new X509SecurityToken(Program.SigningCertificate); SecurityKeyIdentifier keyIdentifier = new SecurityKeyIdentifier(signingToken.CreateKeyIdentifierClause()); SigningCredentials signingCredentials = new SigningCredentials(signingToken.SecurityKeys[0], SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest, keyIdentifier); assertion.SigningCredentials = signingCredentials; // Build the SAML token SamlSecurityToken token = new SamlSecurityToken(assertion); SecurityKeyIdentifierClause attachedReference = token.CreateKeyIdentifierClause(); SecurityKeyIdentifierClause unattachedReference = token.CreateKeyIdentifierClause(); // // Write the XML // // RSTR writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestSecurityTokenResponse, Constants.WSTrust.NamespaceUri.Uri); if (context != null) { writer.WriteAttributeString(Constants.WSTrust.Attributes.Context, context); } // TokenType writer.WriteElementString(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.TokenType, Constants.WSTrust.NamespaceUri.Uri, Constants.WSTrust.TokenTypes.Saml10Assertion); // RequestedSecurityToken (the SAML token) SecurityTokenSerializer tokenSerializer = new WSSecurityTokenSerializer(); writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestedSecurityToken, Constants.WSTrust.NamespaceUri.Uri); tokenSerializer.WriteToken(writer, token); writer.WriteEndElement(); // INSERT DISPLAY TOKEN INTO RSTR (not in original sample) writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "RequestedDisplayToken", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayToken", Constants.WSIdentity.NamespaceUri.Uri); // given name writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayClaim", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteAttributeString("Uri", ClaimTypes.GivenName); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayTag", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString("First Name"); writer.WriteEndElement(); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "Description", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString(ClaimTypes.GivenName); writer.WriteEndElement(); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayValue", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString("Martin"); writer.WriteEndElement(); writer.WriteEndElement(); // surname writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayClaim", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteAttributeString("Uri", ClaimTypes.Surname); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayTag", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString("Last Name"); writer.WriteEndElement(); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "Description", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString(ClaimTypes.Surname); writer.WriteEndElement(); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayValue", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString("Parry"); writer.WriteEndElement(); writer.WriteEndElement(); // email writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayClaim", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteAttributeString("Uri", ClaimTypes.Email); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayTag", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString("Email Address"); writer.WriteEndElement(); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "Description", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString(ClaimTypes.Email); writer.WriteEndElement(); writer.WriteStartElement(Constants.WSIdentity.NamespaceUri.Prefix, "DisplayValue", Constants.WSIdentity.NamespaceUri.Uri); writer.WriteString("martinparry@hotmail.com"); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); // END DISPLAY TOKEN // RequestedAttachedReference writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestedAttachedReference, Constants.WSTrust.NamespaceUri.Uri); tokenSerializer.WriteKeyIdentifierClause(writer, attachedReference); writer.WriteEndElement(); // RequestedUnattachedReference writer.WriteStartElement(Constants.WSTrust.NamespaceUri.Prefix, Constants.WSTrust.Elements.RequestedUnattachedReference, Constants.WSTrust.NamespaceUri.Uri); tokenSerializer.WriteKeyIdentifierClause(writer, unattachedReference); writer.WriteEndElement(); // RSTR End writer.WriteEndElement(); } } }