0

I am storing the token in request header using ajax and sending it to Rest web api. This is my request sent to web api:

  var xhr = new XMLHttpRequest();
            $.ajax({
                url: 'http://localhost:32253/api/UserDetail/Authenticate',
                headers: {
                    "Authorization-Token": res, 
                    "X-HTTP-Method-Override": "GET"
                },
                type: 'GET',
                async: false,
                contentType: "application/json",
                dataType: 'json',
                success: function (data) {
                    alert("Success from success callback!");
                    // ShowData(data);                    
                    $('#RId').text(data.RoleId);
                    $('#RDesc').text(data.RoleDescription);
                    $('#RName').text(data.RoleName);
                },
                error: function (xhr, status) {
                    alert(status);
                }
                //complete: function (data) {
                //    alert("Success!from complete function");
                // } 
            });

On the server side(rest web api), I am trying to read the header

if (Request.Headers.Contains("Authorization-Token"))
            {
                var token = Request.Headers.GetValues("Authorization-Token").First();
}

But the request does not contain the header "Authorization-Token". I can see the header name in Access-Control-request-Headers. I do not know how to read its value. Can someone help me out. I have enabled cors too

UPDATE Now i am passing the token using standard Authorization header of request object

$.ajax({
                url: 'http://localhost:32253/api/UserDetail/Authenticate',
                beforeSend: function (xhr) {
                    xhr.setRequestHeader("Authorization", "Basic " + res);
                },
                type: 'GET',
                async: false,
                contentType: "application/json",
                dataType: 'json',
                authorization: res,
                success: function (data) {
                    alert("Success from success callback!");
                    // ShowData(data);                    
                    $('#RId').text(data.RoleId);
                    $('#RDesc').text(data.RoleDescription);
                    $('#RName').text(data.RoleName);
                },
                error: function (xhr, status) {
                    alert(status);
                }
                //complete: function (data) {
                //    alert("Success!from complete function");
                // } 
            });

but i cannot find it in request headers. See the image for more details Request header

REQUEST LOG This is the request received at the server side

OPTIONS /api/UserDetail/Authenticate HTTP/1.1
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.5
Host: localhost:32253
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization-token,content-type
Origin: http://localhost:14576
Harshitha K
  • 9
  • 1
  • 7

3 Answers3

0

Try sticking with standard header names. It's possible that the value isn't getting passed along though all the network hops. Use the Authorization header with a Bearer scheme as this is standard and then in C# it's a standard property as well.

"Authorization" : "Bearer sometoken"

var header = this.Request.Headers.Authorization;
if(header != null && header.Scheme == "Bearer") { /* do something with header.Value */ }

If you must use a non-standard header, prefix it with X, ex:

"X-Authorization-Token" : "sometoken"

Any proxies or routers are supposed to let X- headers go through with no problems.

UPDATE

Try setting the headers using the beforeSend option:

beforeSend: function (xhr) {
    xhr.setRequestHeader('Authorization-Token', res);
},
ManOVision
  • 1,853
  • 1
  • 12
  • 14
  • I tried both but none worked. Incase of Request.Headers.Authorization, Authorization value is null. Incase of the prefix, i can see the header name in Access-Control-request-Headers but Request.Headers throws an exception "The given header was not found" – Harshitha K Feb 19 '16 at 05:13
  • Does it work when running under localhost? Maybe we can isolate it to a CORS issue. – ManOVision Feb 19 '16 at 05:14
  • I noticed you're using the X-HTTP-Method-Override header as well. Double check that handlers code to make sure it's not stripping any headers. You could put a break point in the Application_BeginRequest method to see if the header is there at the start of the request and if it is there, but not on your controller then you have something intercepting it. – ManOVision Feb 19 '16 at 05:19
  • I just looked at your js code again and noticed it was already pointing to localhost so CORS is not the problem. If you are hitting your same domain with your js app as your api, then you can remove CORS all together. – ManOVision Feb 19 '16 at 05:21
  • I am passing the Auth-token in the request header using c# code and made a request to rest web api, the request received in web api contains the header whereas if i pass the token using ajax, it throws an exception "header not found". – Harshitha K Feb 19 '16 at 05:24
  • I have removed cors. I am facing the same problem. Is there any other way we can pass the token in request header using javascript?? – Harshitha K Feb 19 '16 at 05:36
  • Try saving the request to a file so you can inspect the actual request that the server is getting: `var context = HttpContext.Current; context.Request.SaveAs(context.Server.MapPath("~/request.txt"), true);` can you post that? – ManOVision Feb 19 '16 at 07:46
  • Perhaps this may be of help? - http://stackoverflow.com/a/19825655/696034 The part about the Access-Control-Allow-Headers header in response to the OPTIONS request, which is sent automatically prior to your GET request. – Daniel Protopopov Feb 19 '16 at 08:48
  • You are right. When i run the application in IE i can access the header in web api. Now how to set the Access-Control-Allow-Headers in response? i have set this on top of my method in web api which accepts the get request _[EnableCors(origins: "http://localhost:14576", headers: "X-Authorization-Token", methods: "POST, GET, OPTIONS")]_ – Harshitha K Feb 19 '16 at 09:57
0

Try following:

var xhr = new XMLHttpRequest();
        $.ajax({
            url: 'http://localhost:32253/api/UserDetail/Authenticate',
            beforeSend: function (xhr) { 
                xhr.setRequestHeader('Authorization-Token', res);
                xhr.setRequestHeader('X-HTTP-Method-Override', "GET");
            },
            type: 'GET',
            async: false,
            contentType: "application/json",
            dataType: 'json',
            success: function (data) {
                alert("Success from success callback!");
                // ShowData(data);                    
                $('#RId').text(data.RoleId);
                $('#RDesc').text(data.RoleDescription);
                $('#RName').text(data.RoleName);
            },
            error: function (xhr, status) {
                alert(status);
            }
            //complete: function (data) {
            //    alert("Success!from complete function");
            // } 
        });

UPDATE: Captured the network and able to find tokens in request headers. See the image for more details

Request

can't say anything without full code.

Vikas Dagar
  • 143
  • 1
  • 1
  • 10
  • i have tried it with web API Code ...its working.. string token = Request.Headers.FirstOrDefault(x => x.Key.ToLower() == "authorization-token").Value.FirstOrDefault(); Iam getting the value of token – Vikas Dagar Feb 19 '16 at 06:09
  • I have added a image of the request made to the web api.. can you look into it? I cannot find the header i am passing – Harshitha K Feb 19 '16 at 06:27
0

Thanks Daniel for your suggestion. The issue was as you told with the OPTIONS Request. I set the Access-Control-Allow-Headers in the response for OPTIONS request. I added the following in global.asax.cs of REST Web API

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:14576");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");

                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Authorization-Token, X-HTTP-Method-Override");
                HttpContext.Current.Response.End();
            }
        }

The client side request code is as follows :

 var xhr = new XMLHttpRequest();
            $.ajax({
                url: 'http://localhost:32253/api/UserDetail/Authenticate',
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('X-Authorization-Token', res);
                    xhr.setRequestHeader('X-HTTP-Method-Override', "GET");
                },
                type: 'GET',
                async: false,
                dataType: 'json',
                success: function (data) {
                    alert("Success from success callback!");
                },
                error: function (xhr, status) {
                    alert(status);
                }
            });

Rest web api code for reading the header :

if (Request.Headers.Contains("X-Authorization-Token"))
            {

                var token = Request.Headers.GetValues("X-Authorization-Token").First();
}

This works just fine.

Thank you guys for your time and suggestions:)

Harshitha K
  • 9
  • 1
  • 7
  • Glad you found it! There is a nuget package to help with this: [Microsoft.AspNet.WebApi.Cors](https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Cors/) then in your WebApiConfig, you just add this `config.EnableCors(new EnableCorsAttribute("domain.com", "*", "*"));` There's a pretty good article from MS [here](http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api). – ManOVision Feb 19 '16 at 14:26
  • I first tried with CORS but it was of no help.. I had enabled CORS in webapiconfig and had added enablecors on my get method too. But it did not help.. finally i uninstalled CORS and tried the above solution and it finally worked.. I do not know why CORS did not work as expected – Harshitha K Feb 20 '16 at 06:48