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();
}
}
}