1

I am creating an HTTP POST request with HttpClient and HttpRequestMessage in c#. The site I am trying to post to has an authentication header that is case sensitive with the name "AUTHORIZATION". When I try to add this header to my c# HttpRequestMessage using the following code:

Req.Headers.Add("AUTHORIZATION", "Bearer " + bearer);

I end up getting a post request that contains a header name "Authorization". I believe this is because it is recognizing my header as an authentication header and is changing it. The problem is that the website checking for this header is case-sensitive. I end up getting a 403 forbidden response as a result.

I have looked everywhere to try and find a solution, but I cannot find anyone with the same issue. Does anyone know how to fix this?

Zamen
  • 11
  • 1
  • Hello, It's a possible duplicate of another post : https://stackoverflow.com/questions/32167804/set-authorization-header-of-httpclient You could add athorization like this : httpClient2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", tokenKey); – Bouam Feb 24 '22 at 10:01
  • The default name for the AuthenticationHeaderValue is "Authorization". That example would give you an output header like this: Authorization: Basic tokenkey I need my header to be: AUTHORIZATION: Bearer bearer – Zamen Feb 24 '22 at 10:04
  • 1
    Actually the site with case sensitive Auth Header is violating RFC2616 https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 that states headers Field names are case-insensitive ... – J.Salas Feb 24 '22 at 10:11
  • Please try to use this : var http = new HttpClient(); http.DefaultRequestHeaders.TryAddWithoutValidation("AUTHORIZATION", "key=XXX"); – Bouam Feb 24 '22 at 10:12
  • Yes, I have also tried that. I believe the only difference between that and just add() is a boolean return value stating if the header has been added. – Zamen Feb 24 '22 at 10:18
  • No TryAddWithoutValidation is ignoring RFC validations. – Bouam Feb 24 '22 at 14:37

1 Answers1

0

I have the same problem, the api that i consumed only works with "AUTHORIZATION" header and i have no control over it. So the only available solution must be on client side. To allow send case sensitive header i use the internal method "TryAddWithoutValidation" of "HttpRequestHeaders" class and "force" the invocation using reflection.

public static class HttpClientExtensions {
       public static void AddCaseSensitive(this HttpRequestHeaders headers, string key, string value)
       {
   
            var reqHeaderType = headers.GetType();
            var tryAddWithoutValidation=reqHeaderType.GetRuntimeMethods()
               .Where(m => m.Name == "TryAddWithoutValidation")
               .FirstOrDefault(m=>{
                   var funcParamenters = m.GetParameters().ToList();
                   var firstParam = funcParamenters.First();
                   var secondParam = funcParamenters.Last();
                   return   firstParam.ParameterType.FullName!= typeof(string).FullName &&   secondParam.ParameterType.Namespace!="System.Collections.Generic";
                });
            var internalHeaderDescriptorType = tryAddWithoutValidation.GetParameters().First().ParameterType;
            var HeaderDescriptor = internalHeaderDescriptorType.GetConstructor(BindingFlags.NonPublic|BindingFlags.Instance,new Type[]{typeof(string)});
            object headerDescriptorInstance = HeaderDescriptor.Invoke(new object[] { key });
    
            tryAddWithoutValidation.Invoke(headers, new object?[] { headerDescriptorInstance,value});
}  }

To use it

var client = new HttpClient();
    client.BaseAddress = new Uri(_config.ApiUrl);
    client.DefaultRequestHeaders.AddCaseSensitive("AUTHORIZATION",$"Token {_config.ApiToken}");

this only was tested with System.Net.Http@4.3.0