Building of Custom Security Token in WCF

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

In some sophisticated scenarios there might be requirement to implement the custom security header. Because this
is not well documented in WCF documentation I decided to post one the example. By implementing of custom security
there will be some custom security token like MySecurityTokenHeader shown in the next example.
In general to implement any kind of header in WCF the customization class has to derive from MessageHeader.

  internal class MySecurityTokenHeader : MessageHeader
{

/// <summary>
///
This method is called by WCF during serialization of the message,
/// when the custom security header has to be created.
///
It traverses trough all created security tokens
/// and append them to the message header.
/// </summary>
/// <param name="writer"></param>
/// <param name="messageVersion"></param>
protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer,
MessageVersion messageVersion)

    foreach (SecurityToken token in m_SomeCustomSecurityTokens)
     
{
        
MySecurityTokenSerializer tokenSerializer = 
         new MySecurityTokenSerializer(token, this.m_MessageVersion);

         tokenSerializer.WriteToken(writer, token); 
      
}
}

/// <summary>
/// The name of the element describing the security header.
/// </summary>
public override string Name

   get { return ElementContainer.Security; }
}

  /// <summary>
  /// Namespace of the security header.
  /// </summary>
  public override string Namespace
  {
   
get { return NamspaceContainer.WssSecuritySecext; }
  }
}


The most important method is OnWriteHeaderContents. It is responsible to create the header with any custom content.
In this example I append many custom security tokens. However, for this purpose the class MySecurityTokenSerializer
is used.

Following example shows how to implement the custom security token serializer which is automatically invoked by Service Model,
when the custom SecurityHeader has to be serialized.

internal class MySecurityTokenSerializer : WSSecurityTokenSerializer
{
private SecurityToken m_Token;

public MySecurityTokenSerializer(SecurityToken token, SecurityVersion version)
: base(version)
{
m_Token = token;
}

	///<summary>
/// Writes the specified security token using the specified XML writer. Called
/// by the base class.
///</summary>
///<param name="writer">The writer used to wite the token data.</param>
///<param name="token">The security token which should be serialized.</param>
protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)
{
            if (m_Token is XmlSecurityToken)
serializeSbbSamlToken(writer, token as XmlSecurityToken);
else
base.WriteTokenCore(writer, token);
}
        private void serializeSbbSamlToken(XmlWriter writer, XmlSecurityToken token)
{
XmlNodeReader reader = new XmlNodeReader(someXmlElementContainingTheToken);
writer.WriteNode(reader, true);
}
}


Posted May 23 2007, 02:19 PM by Damir Dobric
Filed under:

Comments

Chris wrote re: Building of Custom Security Token in WCF
on 12-13-2007 2:28

Hi!

Greate Article!

I also want to write a custom MessageHeader. I want to attach it in a client interceptor an get it on the serverside in a server interceptor.

My problem is: How can I share the MyHeader Type bewteen Client and Server, so tha I can do that on the client side:

request.Headers.Add(new MyHeader ());

and that on the serverside:

MyHeader header = new MyHeader;

header = request.Headers.GetHeader<MyHeader>(header.Name, header.Namespace);

Thank you!!!

Damir Dobric wrote re: Building of Custom Security Token in WCF
on 12-13-2007 8:20

Hi Chris,

In general, there are two ways how to do that:

1. Binary Share

You use the same library at both sides. This is not a        real SOA approach, but anytime you are going to make changes in the protocol it will be necessary to do that. If your app is designed for .NET30, this should not be a problem.

2. There are two implementations of the same thing. In a case of MessageHeader, this is not  a big problem, because the message header just keeps a list of some “strings”, semantically describe something. However the reusability of this is not well 

Last but not least, I’m not sure that exactly the same functionality in context o Message Header has to be implemented on both sides. Usually, I would expect that client appends something to header and service reads it (and vice versa in duplex scenario).

Hope this helps you.

James Syed wrote re: Building of Custom Security Token in WCF
on 05-09-2008 23:44

There was an error serializing the security token

I get the above error when I rin your code. Any ideas what I am doing wrong?

Damir Dobric wrote re: Building of Custom Security Token in WCF
on 05-09-2008 23:51

Could you please describe the error?

ktk wrote re: Building of Custom Security Token in WCF
on 05-15-2009 20:03

I'm getting an error saying 'type or namespace XmlSecurityToken  could not be found'. does this need to be defined somewhere?

Damir Dobric wrote re: Building of Custom Security Token in WCF
on 05-16-2009 20:06

Can you post the code?

ktk wrote re: Building of Custom Security Token in WCF
on 05-18-2009 23:45

Thanks Damir. I appreciate your help. I'm posting the code blocks here:

//////////////////////////////////

//This is from Damir's Blog

/////////////////////////////////

   internal class MySecurityTokenSerializer : WSSecurityTokenSerializer

   {      

       private SecurityToken m_Token;

       public MySecurityTokenSerializer(SecurityToken token, SecurityVersion version) : base(version)        

       {            

           m_Token = token;        

       }

///<summary>        

       /// Writes the specified security token using the specified XML writer. Called        

       /// by the base class.        

       ///</summary>        

       ///<param name="writer">The writer used to wite the token data.</param>        

       ///<param name="token">The security token which should be serialized.</param>      

       protected override void WriteTokenCore(XmlWriter writer, SecurityToken token)      

       {

           if (m_Token is XmlSecurityToken)    

               serializeSbbSamlToken(writer, token as XmlSecurityToken);    

           else

               base.WriteTokenCore(writer, token);        

       }

       private void serializeSbbSamlToken(XmlWriter writer, XmlSecurityToken token)        

       {

           XmlNodeReader reader = new XmlNodeReader(token);          

           writer.WriteNode(reader, true);        

       }    

   }

/////////////////////////////////////////////////////////////////////

//This is my calling code

/////////////////////////////////////////////////////////////////////

           Claim[] claims = new Claim[]

           {

               new Claim(@"schemas.xmlsoap.org/.../upn",

                   "Someone@hotmail.com")

           };

//my internal method to get a security token from my STS

           SecurityToken stsToken = CreateSTSToken(claims);

           SecurityVersion version = SecurityVersion.WSSecurity11;

           MySecurityTokenSerializer serializer = new MySecurityTokenSerializer(stsToken, version);

           StringBuilder stringBuilder = new StringBuilder();

           XmlWriter xr = XmlWriter.Create(new StringWriter(stringBuilder), new XmlWriterSettings { OmitXmlDeclaration = true });

           serializer.WriteToken(xr, stsToken);

//////////////////////////////////////////////////////////////////////

Alex wrote re: Building of Custom Security Token in WCF
on 06-27-2009 4:15

I've tried this exact code and it does work, however, there is a problem when it comes to signing the token with a pki cert.

When WCF signs a message, it doesn't care what has been written to the xml message stream, it goes directly to the object. This can be a problem if you write out a custom attribute in a way that is different from that of the standard serializer.Serialize (this) method. There has to be another way. Any ideas?

Damir Dobric wrote re: Building of Custom Security Token in WCF
on 06-27-2009 15:51

Please take a look here: developers.de/.../signing-xml-documents.aspx

Thi smight be helpful. Signing in context of WCF ist mostly very complex topic, because it is not well documented etc.

developers.de is a .Net Community Blog powered by daenet GmbH.