Sunday, October 30, 2011

Creating a secure RESTfull wcf service and consume it cross domain with jquery using basic authentication

Last week I was very busy trying to create a secure wcf service which can be consumed using jquery jquery and wcf. There are a lot of resources (see References below) but none of them contain the full working package. Below I try to highlight the steps of creating the service and consumer. And because a sample says more than a thousand words, you can download it here.

The solution only works when the wcf service is hosted using iis. I have not tried to create the service using the self-hosting feature of wcf.

Note 2:
For basic authentication to be secure, you need to access it using SSL.

Step 1. Create your basic interface using the WebGet and WebInvoke
[WebGet(UriTemplate = "get/Do/{echo}", ResponseFormat = WebMessageFormat.Json)]
DoResponse Do(string echo);

[WebInvoke(Method = "POST", UriTemplate = "post/Do/{echo}", ResponseFormat = WebMessageFormat.Json)]
DoResponse DoPost(string echo);

Step 2. Enable cross domain calls using the global.asax
protected void Application_BeginRequest(object sender, EventArgs e)

private void EnableCrossDomainAjaxCall()
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept");

Step 3. Configure the basic html module
        <binding name="BasicAuthentication">
            <security mode="TransportCredentialOnly">
                <transport clientCredentialType="Basic" />

    <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
    <serviceMetadata httpGetEnabled="true"/>
    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
    <serviceDebug includeExceptionDetailInFaults="false"/>
    <serviceAuthorization serviceAuthorizationManagerType="WcfSampleApp.Wcfservice.BasicAuthorization, WcfSampleApp.Wcfservice" />

Step 4. Call the service using jquery ajax using basic authentication header.
$.ajax( {
 url : 'http://localhost:35461/SampleApp.svc/get/Do/same problem',
 dataType: 'json',
 type: "GET",
 beforeSend : function(xhr) {
     xhr.setRequestHeader("Authorization", "Basic " + encodeBase64("sameproblem:morecode"));
 error : function(xhr, ajaxOptions, thrownError) {
 success : function(model) {

Download example solution