Custom Cookies in WCF With C#

Introduction

This article provides a short description of Custom Cookies. Custom Cookies can be implemented in a WCF Service and they do not need to be managed with a special handling. That means the handling of Custom Cookies is very easy. Let us see, the example of Custom Cookies can be passed over the HTTP Header in WCF Services.

A cookie is a collection of key/value pairs that are stored within the HTTP header to the client. If cookies are set, then it is distributed over the client and server architecture.



Message inspectors allows modification of all incoming or outgoing messages in the WCF messaging pipeline that transit on the server-side as well as on the client-side. The inspectors that are registered with the WCF runtime receive the messages before they are passed on to the application or sent to the wire, depending on whether it is an incoming or outgoing message. The cookies were designed to keep the stateful information or record the client's details and their activities.

All HTTP responses are caught that comes from the web server, extract any cookies contained within the messages and manually inject them in all subsequent HTTP requests on their way out. The cookie has the following features:

  • A Cookie cannot carry the viruses.
  • A Cookie cannot install the harmful/undesired programs into server machines.
  • A Cookie can be easily managed.
  • A Cookie is distributed in Non-Plain/Un-readable format over the network.
  • The cookie is encrypted with the private key over the network and encryption/decryption is managed automatically. No need to handle the encryption and decryption mechanism by the programmer.

Building the Sample

Here, it shows the example of outgoing and incoming Custom Cookies over the client and server service model.

This example demonstrates how a client can check whether or not the service is alive.

Server-Side Samples

For cookies the service must have the ASPNET compatibility and the compatibility can be managed in the configuration file as well.

  1. <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>  
  2. // Server Side Program  
  3. if (WebOperationContext.Current != null)  
  4. {  
  5.    // Here you can see the IncomingRequest Header is providing the incoming Cookies.  
  6.    string cookieHeader  
  7.    =WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie];  
  8.    // Here you can see the OutgoingResponse Header has set the cookies.  
  9.    if (cookieHeader == null)  
  10.    {  
  11.       Guid sessionId = Guid.NewGuid();  
  12.       WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.SetCookie]  
  13.       =string.Format("SessionID={0}", sessionId);  
  14.       return sessionId;  
  15.    }  
  16.    Match match = Regex.Match(cookieHeader, @"^SessionID=(?<SessionID>.*)$");  
  17.    if (match.Success)  
  18.    {  
  19.       return new Guid(match.Groups["SessionID"].Value);  
  20.    }  
  21. }  
Custom Cookies can be used to handle the sessions and details are provided to the client.
  1. SessionAuthority.SessionCollector sessionCollector = SessionAuthority.GetSessionDetail();  
  2. return string.Format("{0} time(s) called for product : {1}"
    sessionCollector.SessionCollectionData[NumberOfTimesCalled], 
    sessionCollector.SessionCollectionData[Product]);  
The preceding snippet is used to get session details and the same details were fetched by the client to check whether or not the server is active.

Binding definition for server:
  1. <bindings>  
  2.    <wsHttpBinding>  
  3.       <binding name="higherMessageSize_WS" closeTimeout="00:01:00"  
  4.       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="03:01:00"  
  5.       bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcar  
  6.       "  
  7.       maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"  
  8.       messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"  
  9.       allowCookies="true">  
  10.       <readerQuotas maxDepth="32" maxStringContentLength="2147483647"  
  11.          maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />  
  12.          <security mode="Transport">  
  13.             <transport clientCredentialType="Windows" />  
  14.          </security>  
  15.       </binding>  
  16.    </wsHttpBinding>  
  17. </bindings>  
In the example above, you can see that the allowCookies parameter is set to "true".

Client-Side Samples
  1. // Client Side Program  
  2. // Enter the Product Detail Or Name  
  3. Console.WriteLine("Enter product :");  
  4. string input = Console.ReadLine();  
  5. Console.WriteLine(Environment.NewLine + "Processing started....");  
  6. // Set or Pass the Product as Cookie  
  7. asyncClient.WriteCookies(input);  
  8. // Invoke the entered Cookie  
  9. IAsyncResult asyncResult = InvokedService(asyncClient, input);  
  10. finaldata = asyncClient.EndGetFinalOutput(asyncResult);  
The code snippet above shows how the cookies were passed for writing into the HTTP Header to the server by the WriteCookies() method.
  1. int i = 0;  
  2. IAsyncResult invokedServicecall = serviceClient.BeginGetFinalOutput(productData, delegate { },null);  
  3. while (invokedServicecall.AsyncWaitHandle.WaitOne(2000) == false)  
  4. {  
  5.    string getStatus = serviceClient.KeepStatus();  
  6.    Console.WriteLine(Environment.NewLine + i + ".The KeepGetStatus = " + getStatus);  
  7.    i++;  
  8. }  
Here above, you can see that the keepstatus() method is providing the status of the service, whether or not it is alive. The cookies were set at the server side for the same.

The following is the binding definition for the client:
  1. <system.serviceModel>  
  2.    <bindings>  
  3.       <wsHttpBinding>  
  4.          <binding name="WSHttpBinding_ICookies" sendTimeout="00:31:00"  
  5.          allowCookies="true">  
  6.          <security mode="Transport">  
  7.             <message algorithmSuite="Default" />  
  8.          </security>  
  9.          </binding>  
  10.       </wsHttpBinding>  
  11.    </bindings>  
  12.    <client>  
  13.       <endpoint address=https://localhost/MyCookies/CookiesSample.svc  
  14.       binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICookies"  
  15.       contract="ServiceCookies.ICookies" name="WSHttpBinding_ICookies">  
  16.          <identity>  
  17.             <dns value="localhost" />  
  18.          </identity>  
  19.       </endpoint>  
  20.    </client>  
  21. </system.serviceModel>  
The allowCookies parameter must be set to "true" at the client side as well.

You can find the debugging details in the debugger as well or Quick Watch for cookies: