Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Article

WCF Service Method Level Security using Message Contract

Rate me:
Please Sign up or sign in to vote.
4.74/5 (19 votes)
23 Jan 2012CPOL5 min read 115.4K   4K   49   14
This article illustrates how to implement security for a service method, in the context of custom authentication, confidentiality and integrity, using Message Contract.

Introduction

This article illustrates how to implement security for a service method, in the context of custom authentication, confidentiality and integrity, using Message Contract. The message is packed with authentication information at the client side in the MessageHeader. The Service intercepts this message and validates the credibility of the consumer client. Besides, we will also check, using Message Contract how can sign or encrypt partial header information and all body information in a message.

Real Life Scenario

There could a service method which is passing sensitive information over the wire and you want to take some exclusive security measure for the service method in question. You can pack a security token in the relevant message header for the service method and validate the same in the service end before returning response. Also, since the information in the message is highly sensitive, you can sign and encrypt the message. We will implement this kind of service method level authentication and message level security for a specific service method, using Message Contract in this article.

Implementing the WCF Service

In order to implement the above discussed concept, we will develop a simple WCF service project. The WCF service has a GetAccountsData method which returns AccountsInfo of a customer on validating CustomerCredential passed as input.

Image 1

The types passed and returned by the service method are defined as Message Contract. In order to Sign/Encrypt the Message parts, we will use protection level. There are three basic levels of protections that exist for any part of a message:

  • None.
  • Sign. The protected part is digitally signed. This ensures detection of any tampering with the protected message part.
  • EncryptAndSign. The message part is encrypted to ensure confidentiality before it is signed.

In order to set protection level, use System.Net.Security namespace.

Image 2

The CustomerCredential Message Contract contains a MessageHeader element SecurityToken, which is being validated at service end.

Image 3

One thing to keep in mind, the SOAP Body has only one protection level, even if you have multiple body parts with different protection levels. In case of AccountsInfo Message Contract, the highest protection level off all body parts will be taken (in our case, EncryptAndSign). SOAP headers can have different protection levels. I have deliberately set different protection level in Message body in order to establish this behavior. We will verify this on checking the HTTP traffic.

Implement the service method. If the SecurityToken matches, the method returns AccountsInfo for the customer, otherwise throws security exception.

Image 4

The default WCF binding BasicHttpBinding does not support protection level. We need to introduce a wsHttp binding for our service. In order to introduce a wsHttp binding, make an entry in the web.config file as follows:

XML
<services>
      <service name="MyWCFService.MyService">
        <endpoint address="" binding="wsHttpBinding" contract="MyWCFService.IMyService"/>
        </service>
</services>

Right click -> View in Browser on the file MyService.svc in order to check the WSDL generated by the WCF service.

Publish the Service in Internet Information Server(IIS)

We could have called the service without publishing it in IIS. But at the end, we are also going to check the Sign/Encryption of messages. We will be checking HTTP traffic using Fiddler tool while the service is being consumed by some client application. For this purpose, we need to publish it in IIS (sometimes Fiddler creates problems while inspecting localhost traffic. There are workarounds for this, but it’s better to publish the service in IIS). Right click on the WCF service application project and click on publish. Create a virtual directory named WCFVW in IIS and publish the service. Modify the target location with your pc name.

Image 5

Browse the newly published service in the browser:

Image 6

Click on the service link and check the WSDL.

Calling the Service

We will create a simple console application in order to consume the service. Add a Console application project. Right click on the References->Add Service Reference. Type the WCF service URL in the Address box.

Image 7

Once you click on OK, the stub code will be generated. Open Program.cs and add the following namespaces:

Image 8

Implement the following code in order to call the service using channel factory. The SecurityToken is being set in the MessageHeader. If the credential matches, the retrieved account detail for the Customer is being printed, otherwise the Fault thrown by the service is displayed in the console.

Image 9

Run the console application. The accounts information will be retrieved as the SecurityToken is matched at the service end.

Image 10

Now modify the client code in order to pass a different SecurityToken.

Image 11

Run the Console application. Fault will be thrown from the service due to the mismatch in the SecurityToken.

Image 12

Checking Message Sign/Encryption

We are now done with the project and it is time to sniff the HTTP traffic between service and client in order to verify desired Sign/Encryption in our Message Contract. Run the HTTP data inspector Fiddler. Now, run the console application in order to call the service. Check the service request traffic:

Image 13

The request traffic consists of the message parts SecurityToken as MessageHeader and CustomerID as MessageBodyMember in the Message Contract CustomerCredential. Since we have set protection level to “EncryptAndSign” for MessageHeader, the SecurityToken has been signed and encrypted. Also, the MessageBodyMember CustomerID is visible as its protection level is set to “None”.

Now check the response message. The returned Message Contract AccountsInfo does not have any MessageHeader. It has got MessageBodyMembers with different protection level. As I have mentioned earlier, the SOAP Body has only one protection level, even if you have multiple body parts with different protection levels. In this case, the highest protection level of all body parts, EncryptAndSign is taken and the entire messagebody becomes signed and encrypted.

Image 14

History

  • 21st January, 2012: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionQuestion on Encryption and Signing Pin
km.ananth845-Jul-16 20:35
km.ananth845-Jul-16 20:35 
PraiseMy vote of 5 Pin
S.S.Cheral30-May-16 2:46
S.S.Cheral30-May-16 2:46 
Questionwhat to do with the error??? Pin
arunmohanmenon23-Feb-15 19:45
arunmohanmenon23-Feb-15 19:45 
QuestionI am getting the error: The request message must be protected. This is required by an operation of the contract ('IMyService','http://tempuri.org/'). The protection must be provided by the binding ('BasicHttpBinding','http://tempuri.org/'). Pin
arunmohanmenon23-Feb-15 19:43
arunmohanmenon23-Feb-15 19:43 
The request message must be protected. This is required by an operation of the contract ('IMyService','http://tempuri.org/'). The protection must be provided by the binding ('BasicHttpBinding','http://tempuri.org/').

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The request message must be protected. This is required by an operation of the contract ('IMyService','http://tempuri.org/'). The protection must be provided by the binding ('BasicHttpBinding','http://tempuri.org/').

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[InvalidOperationException: The request message must be protected. This is required by an operation of the contract ('IMyService','http://tempuri.org/'). The protection must be provided by the binding ('BasicHttpBinding','http://tempuri.org/').]
System.ServiceModel.Dispatcher.ContractProtectionRequirementsRule.ValidateBindingProtectionCapability(Binding binding, ContractDescription contract, ProtectionLevel request, ProtectionLevel response) +16491388
System.ServiceModel.Dispatcher.SecurityValidationBehavior.ValidateNoSecurityBinding(Binding binding, ContractDescription contract) +71
System.ServiceModel.Dispatcher.SecurityValidationBehavior.System.ServiceModel.Description.IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase) +143
System.ServiceModel.Description.DispatcherBuilder.ValidateDescription(ServiceDescription description, ServiceHostBase serviceHost) +301
System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +334
System.ServiceModel.ServiceHostBase.InitializeRuntime() +82
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +64
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +789
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +255
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +1172

[ServiceActivationException: The service '/MyService.svc' cannot be activated due to an exception during compilation. The exception message is: The request message must be protected. This is required by an operation of the contract ('IMyService','http://tempuri.org/'). The protection must be provided by the binding ('BasicHttpBinding','http://tempuri.org/')..]
System.Runtime.AsyncResult.End(IAsyncResult result) +900192
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +192830
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +107
QuestionVery usefull post Pin
vikas palav6-Jan-14 22:19
vikas palav6-Jan-14 22:19 
GeneralMy vote of 5 Pin
ankurbhutani13-Sep-13 9:05
ankurbhutani13-Sep-13 9:05 
GeneralMy vote of 5 Pin
upenn8725-Apr-13 1:59
upenn8725-Apr-13 1:59 
QuestionEncrypted Algorithm Pin
Keizer61921-Apr-13 21:31
Keizer61921-Apr-13 21:31 
QuestionHow to deploy over internet?? Pin
CiaranCoyle16-Jan-13 6:26
CiaranCoyle16-Jan-13 6:26 
QuestionWCF Service Method Level Security using Message Contract Pin
Sokka_sta18-Oct-12 20:55
Sokka_sta18-Oct-12 20:55 
GeneralMy vote of 5 Pin
maicalal23-May-12 6:04
maicalal23-May-12 6:04 
QuestionHow to use fiddler to check the request and response message Pin
Member 381226425-Apr-12 2:34
Member 381226425-Apr-12 2:34 
AnswerRe: How to use fiddler to check the request and response message Pin
Kausik J. Nag5-May-12 19:36
Kausik J. Nag5-May-12 19:36 
GeneralMy vote of 5 Pin
Hassan Shafipour23-Jan-12 10:18
Hassan Shafipour23-Jan-12 10:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.