简体   繁体   中英

C# HttpClient POST requests from Azure Function with Authorization tag intended for third-party API are stripped of Headers and Body

UPDATE

I was able to get a working request posted. The third-party API has us sending the Token (which is basically a Guid) as a bearer token. Azure appears to do some sort of pre-validation on this. When I swapped out the GUID with a true randomly generated bearer token, it worked.

I do still wonder if there's a way to disable this check-in Azure. The "bad" Bearer token works for GET requests but fails for POST/PUT requests.

Summary of the Application We have Azure Functions (ie, Time Trigger, Orchestrator, Activities) that look for items in an on-prem queue table in SQL and then POST it to a third-party API via JSON.

The third-party API requires an Authorization header with the POST request.

Technical Overview

  • dotnet core 3.1
  • azure function runtime ~3

Additional Information

  • This codebase worked fine during UAT back in April-May of this year. It then sat idle until we rebooted the project a couple of weeks ago.
  • Outbound requests are not proxied through APIM. They're sent directly to the third-party API
  • Application Insights is configured for the Azure Function

What works All of the GET requests. No issues at all.

What doesn't work POST requests. I proxied the requests to a beeceptor to see exactly what was being received. When the Authorization header is included most of the headers are stripped (Ie, Content-Type, Content-Length) and the Body of the request is blank.

If I removed the Authorization header then all headers and body are received as expected.

Question I can only assume at this point that some Azure service, pre-flight check, security policy is intercepting the Authorization header thinking it's intended for "itself", but I have absolutely no idea what it could be. I've been on Google now for days.

Simplified Version of Code

using var client = new HttpClient();
client.DefaultRequestHeaders.Clear();

// Request params are dynamic and a helper method builds the full request path
var path = PathBuilder(queueItem.RequestParams, queueItem.Request.UrlPath);

// This can change in code not shown if the request is sending files
var contentType = "application/json";

client.BaseAddress = new Uri(queueItem.Request.Client.BaseApiUrl);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", queueItem.Request.Client.AuthToken);

// queueItem.Data is JSON
HttpContent json = new StringContent(queueItem.Data, Encoding.UTF8, contentType);
return await client.PostAsync(path, json);

Also...

  • I've confirmed the JSON body is valid
  • The code did work and has remain unchanged

Given all that you've tried, it might be a long shot, but have you tried to add the token like client.DefaultRequestHeaders.TryAddWithoutValidation(“Authorization”, “bearer token here…”); and then check whether the try succeeded or not?

The solution to the problem? Don't neglect unit tests even at the DB layer. In short, the issue doesn't have to do with Azure, but more so with how the data was (or wasn't) fed to it.

Thank you to everyone who provided insight and suggestions. All of you helped me work towards a solution through the process of elimination.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM