Search code examples
c#jsonauthorizationhttp-status-code-401google-cloud-automl

Receiving 401 "Unauthorized" error while using Google Cloud AutoML via HttpClient


I am writing a WPF application with C# that attempts to make an Google Cloud AutoML API call with HttpClient. I am able to make contact with the server but always get back an "Unauthorized" response. I have scoured StackOverflow and the AutoML documentation for any hint as to how to properly turn the "CURL" request into a simple HTTP request that I can execute programmatically within my C# application, but haven't found anything that gave enough guidance up to this point (hence my question).

Here is the CURL request that I am modeling my HTTP request after:

curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  https://automl.googleapis.com/v1beta1/projects/image-object-detection/locations/us-central1/models/MyProjectId:predict -d @request.json

There are elements of this request that I cannot figure out how to translate into C#, namely the Authorization: Bearer component. Do I need to somehow find a token and add it to a header or something? If so, how do I acquire this token in string form? That seems to be what I'm really stuck on.

And here is the C# code that I actually have up to this point.

public async Task<object> GetPrediction(string imagePath)
{
    string apiKey = "MyApiKey";
    string projectId = "MyProjectId";

    HttpResponseMessage response;
    byte[] img = File.ReadAllBytes(imagePath);

    string jsonBody = "{\"payload\":{\"image\":{\"imageBytes\":\"" + Encoding.UTF8.GetString(imgBody) + "\"}}}";
    string uri = $"https://automl.googleapis.com/v1beta1/projects/image-object-detection/locations/us-central1/models/{projectId}:predict?key={apiKey}";
    string token = “MyToken”;

    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Post, uri);
    request.Headers.TryAddWithoutValidation("Content-Type", "application/json");
    request.Headers.Authorization = new AuthenticarionHeaderValue(“Bearer”, token);
    request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

    response = await client.SendAsync(request);

    return Task.FromResult(response);                  
}

This code basically makes contact, then I get back a 401 "unauthorized" status code. Any suggestions or guidance would be greatly appreciated, and if additional information is required, I would be glad to post more. Thanks!

Update:

I modified the code block to include the suggested change from Nkosi, but I am still seeing the same 401 status code.


Solution

  • I am not seeing the Authorization header added to request

    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)"
    

    like in the cURL example

    set the Authorization on the request before sending it

    //...
    
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "{token-here}");
    
    //...