Adding authorization to the headers
Asked Answered
M

5

35

I have the following code:

...
AuthenticationHeaderValue authHeaders = new AuthenticationHeaderValue("OAuth2", Contract.AccessToken);
string result = await PostRequest.AuthenticatedGetData(fullUrl, null, authHeaders);
return result; 
...

public static async Task<string> AuthenticatedGetData(string url, FormUrlEncodedContent data, AuthenticationHeaderValue authValue)
{

    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authValue.Parameter);

    HttpResponseMessage response = await client.PostAsync(new Uri(url), data);

    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    return responseBody;
}

The response = await part just continues an ongoing loop and nothing happens. Any ideas what I am doing wrong?

The question really is, how do I send the following header:

Authorization: OAuth2 ACCESS_TOKEN

to an external web api

Marileemarilin answered 26/9, 2013 at 21:58 Comment(0)
W
35

This line

client.DefaultRequestHeaders.Authorization = 
           new AuthenticationHeaderValue(authValue.Parameter);

Will produce this header value

Authorization: ACCESS_TOKEN

Where ACCESS_TOKEN is the value of authValue.Parameter. You want to assign the value you passed instead to get the required header

client.DefaultRequestHeaders.Authorization = authValue;

Will produce

Authorization: OAuth2 ACCESS_TOKEN
Wise answered 26/9, 2013 at 22:45 Comment(1)
I can now see this working. DefaultRequestHeaders are set as you say. Should I assume that because it is not working, I am not sending the right header stuff through, I had a peak at OAUTH documentation and saw it has a few more values to send... although he api I am working with explicitly says you "need to make future api requests with the above header"Marileemarilin
I
78

I struggled with this. I kept getting an error saying "invalid format" because I have a custom implementation and the Authorization header is validated against certain standards. Adding the header this way however worked:

var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
Intend answered 4/7, 2014 at 13:43 Comment(6)
While this header may appear weird, it is the format in which Authorization header was required by Google Cloud Messaging Service, which in turn sends messages to Android devices.Thoroughgoing
It took me an hour to get this :(. thank you very much.Fluker
Has anyone tested this in windows 10 yet? It still fails even if you use this bypass method. It's infuriating.Hasp
Can't think why it would be a problem with windows 10 surely the .net code is the same ?Intend
This did not work for me. Had to resort to the good old HttpWebRequest, which seems to accept the header in Google's format alright.Widdershins
Worked fine for me; thank you! Saved my hair. http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", myVariableWithCustomAuthFormat);Swanherd
W
35

This line

client.DefaultRequestHeaders.Authorization = 
           new AuthenticationHeaderValue(authValue.Parameter);

Will produce this header value

Authorization: ACCESS_TOKEN

Where ACCESS_TOKEN is the value of authValue.Parameter. You want to assign the value you passed instead to get the required header

client.DefaultRequestHeaders.Authorization = authValue;

Will produce

Authorization: OAuth2 ACCESS_TOKEN
Wise answered 26/9, 2013 at 22:45 Comment(1)
I can now see this working. DefaultRequestHeaders are set as you say. Should I assume that because it is not working, I am not sending the right header stuff through, I had a peak at OAUTH documentation and saw it has a few more values to send... although he api I am working with explicitly says you "need to make future api requests with the above header"Marileemarilin
U
15

Had a similar issue when getting AuthenticationHeaderValue to work with my requests. I was also using JWT JsonWebToken from GitHub. I was able to get a token from the API, but was struggling to use it in other GETs and POSTs.

var jwt = JsonWebToken.Encode(token, APISECRET, JwtHashAlgorithm.HS256);
var tk = GetTokenFromApi(); // basically returns an encrypted string.

Manually using WebRequest: Which worked fine.

request.ContentType = "application/json";
request.Method = "POST";
request.Headers.Set("Authorization", string.Format("Bearer {0}", tk));

When we switched to an HttpClient, and used the AuthenticationHeaderValue, could not figure out how to set it up correctly.After looking at the request string, i saw it added the "Authorization" for me. Played around with parameters, and this finally this worked.

 var authenticationHeaderValue = new AuthenticationHeaderValue("Bearer", tk);
Unbiased answered 20/12, 2017 at 19:57 Comment(0)
L
4

In your code you are doing this:

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", $"{token}");

I think the following should work the same manner without using string interpolation:

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

This is because the string interpolation is just generating a string with the token in it!

Lantana answered 8/9, 2020 at 17:14 Comment(0)
L
2

Maybe intresting for other people. Since I searched on this for a long time. But you have to save your cookies also and give it with your next request. First this is how i got my authentication code and hold my cookies in a static variable (in the first time i call this method I give an empty value to token).

    public static CookieContainer CookieContainer;
    public static async Task<string> Post<TRequest>( TRequest requestBody, string path, string token = "")
    {
        var baseUrl = new Uri($"urlFromApi");
        CookieContainer = new CookieContainer();
        using (var handler = new HttpClientHandler() { CookieContainer = CookieContainer })
            using(var client = new HttpClient(handler){BaseAddress = baseUrl})
        {
            client.DefaultRequestHeaders.ConnectionClose = false;
            if (!string.IsNullOrWhiteSpace(token))
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", $"{token}");
            }
            ServicePointManager.FindServicePoint(client.BaseAddress).ConnectionLeaseTimeout = 60 * 1000; //1 minute            using (var content = new ByteArrayContent(GetByteData(requestBody)))
            using (var content = new ByteArrayContent(GetByteData(requestBody)))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                var response = await client.PostAsync(String.Empty, content);
                return await GetResponseContent(response);
            }
        }

    }

After this if I do any request to the api I include the cookies (token is what you get from the first response as a result) public static async Task Get(string path, string token = "") {

        var baseUrl = $"https://innoviris-ai.collibra.com/rest/2.0{path}";
        using (var handler = new HttpClientHandler() { CookieContainer = CookieContainer })
        using (var client = new HttpClient(handler) {BaseAddress = new Uri(baseUrl)})
        {
            client.DefaultRequestHeaders.ConnectionClose = false;
            if (!string.IsNullOrWhiteSpace(token))
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", $"{token}");
            }
            ServicePointManager.FindServicePoint(client.BaseAddress).ConnectionLeaseTimeout = 60 * 1000; //1 minute     

            var response = await client.GetAsync(String.Empty);
            return await GetResponseContent(response);
        }
    }
Loganloganberry answered 24/3, 2019 at 21:35 Comment(1)
"${token}" is redundant. It's equivalent to string.Format("{0}", token) where token is already a string.Splashy

© 2022 - 2024 — McMap. All rights reserved.