1

Hi I have simplified my code as much as possible below. What I am trying to achieve is call a restful wcf service.However when I add the set request header method I get exception, in both Firefox and chrome, but it works in IE it successfully hits the service method.

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

    <script type="text/javascript" src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-md5.js"></script>
    <script type="text/javascript" src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script type="text/javascript">

    function WriteResponse(string) {        
        $("#divResult").val(string);
    }

    function setHeader(xhr) {
        var secretkey = "1234dgt";
        var hashedUrl = CryptoJS.HmacMD5($('#txtUrl').val(), secretkey);
        var hashedUrlBase64 = hashedUrl.toString(CryptoJS.enc.Base64);
        xhr.setRequestHeader('Authorization', hashedUrlBase64, "1234dgt");
    }

    $(document).ready(function () {
        $("#btnCall").click(function () {

            jQuery.support.cors = true;
            $.ajax({               
                url: $('#txtUrl').val(),
                type: 'GET',
                async: false,
                dataType: 'json',
                success: function (data) {
                    WriteResponse(data);
                },
                error: function (x, y, z) {
                    alert(x + '\n' + y + '\n' + z);
                },
                beforeSend: setHeader
            });
        });
    });

</script>

Any help would be much appreciated.
Thanks

// Here is the c# code used to call the same service:
public static string GetUserBookmarks(string uri)
    {
        HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
        string encodedUri = EncodeText(_key, uri, UTF8Encoding.UTF8);
        request.Headers[HttpRequestHeader.Authorization] = encodedUri;
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
        Stream bookmarksStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(bookmarksStream);
        string str = reader.ReadToEnd();
        reader.Close();
        bookmarksStream.Close();
        return str;
    }

    public static string EncodeText(string key, string text, Encoding encoding)
    {
        HMACMD5 hmacMD5 = new HMACMD5(encoding.GetBytes(key));
        byte[] textBytes = encoding.GetBytes(text);
        byte[] encodedTextBytes =
            hmacMD5.ComputeHash(textBytes);
        string encodedText =
            Convert.ToBase64String(encodedTextBytes);
        return encodedText;
    }



// Here is the wcf service method and its interface\contract

[ServiceContract]
public interface IRestSerivce
{
    [WebGet(UriTemplate = "users/{username}")]
    [OperationContract]
    List<string> GetUserBookmarks(string username);

}



public List<string> GetUserBookmarks(string username)
    {
        WebOperationContext context = WebOperationContext.Current;
        OutgoingWebResponseContext outgoingResponseContext =
            context.OutgoingResponse;

        bool isUserAuthenticated = IsUserAuthenticated(username);
        if (isUserAuthenticated == false)
        {
            outgoingResponseContext.StatusCode = HttpStatusCode.Unauthorized;
            return null;
        }

        outgoingResponseContext.StatusCode = HttpStatusCode.OK;

        List<string> bookmarks = new List<string>();
        bookmarks.Add("User has been authenticated Successfully");

        return bookmarks;
    }

Here is the error I am receiving, this is the alert in the ajax error function producing this, however there are no errors in the firbug console window.

[object Object] error [Exception... "Failure" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://code.jquery.com/jquery-1.9.1.min.js :: .send :: line 5" data: no]

2 Answers 2

0

Can you please have a look at this stackoverflow question, I think it demonstrates what you are trying to achieve.

I think you're passing one parameter too many to setRequestHeader.

Sign up to request clarification or add additional context in comments.

12 Comments

Hi, unfortunately removing either the second or third param to the setRequestHeader method produces the same error.
Can you call the service successfully by some other way, e.g. via a small C# console application? So you can eliminate any other problems like wrong salt or similar trivial issues.
Hi Nikolaos, yes I can call the service fine via a c# console app. I could send you sample code. I have wcf restful service being called by c# console app and also via web app. If i remove the set header method it works fine. I cannot find any help on the web for this matter.
and you're generating the Authorization header the same way in the C# app? MD5 hash of the target URL with a secret key and then base64 the entire thing? one more thing you can try is instead of using the beforeSend function, use the headers attribute. Check out the second answer in this question
Hi do you have an email I can send this to?
|
0

I finally found the issue with my code, it was due to Authorization headers not being allowed server side. So to solve the issue I needed to add some code to the global.asac.cs class of my wcf project. The below code also enables cross domain calls.

    protected void Application_BeginRequest(object sender, EventArgs e)
    {

        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();

        EnableCrossDmainAjaxCall();
    }

    private void EnableCrossDmainAjaxCall()
    {
        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, Accept, Authorization");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age",
                          "1728000");
            HttpContext.Current.Response.End();
        }
    }

Thank you to Nikolaos for your help.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.