Adding authorization to the headers

97,286

Solution 1

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

Solution 2

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");

Solution 3

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);

Solution 4

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);
        }
    }

Solution 5

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!

Share:
97,286

Related videos on Youtube

Jimmyt1988
Author by

Jimmyt1988

Updated on September 09, 2020

Comments

  • Jimmyt1988
    Jimmyt1988 over 3 years

    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

  • Jimmyt1988
    Jimmyt1988 over 10 years
    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"
  • Parth Shah
    Parth Shah over 9 years
    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.
  • Anupam Singh
    Anupam Singh about 9 years
    It took me an hour to get this :(. thank you very much.
  • Sinaesthetic
    Sinaesthetic over 8 years
    Has anyone tested this in windows 10 yet? It still fails even if you use this bypass method. It's infuriating.
  • John
    John over 8 years
    Can't think why it would be a problem with windows 10 surely the .net code is the same ?
  • Exulted
    Exulted over 6 years
    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.
  • eidylon
    eidylon almost 3 years
    Worked fine for me; thank you! Saved my hair. http.DefaultRequestHeaders.TryAddWithoutValidation("Authoriz‌​ation", myVariableWithCustomAuthFormat);
  • Jonathan Gilbert
    Jonathan Gilbert over 2 years
    "${token}" is redundant. It's equivalent to string.Format("{0}", token) where token is already a string.