I am trying to implement a Xamarin app that works with the Asana API.
I have successfully implemented the OAuth as documented in the Asana documentation here... at least I assume it is successful. I get an access token from the token endpoint in an HTTPResponse with HTTP Status "OK".
But then when I turn around and try to make an API call with that same access token, I get a 403 Forbidden error. I tried the same API call in my browser (after logging in to Asana), and it works fine, which leads me to believe that I do have access to the resource, I must have an issue with authorizing the request on my end.
The API call in question is (documented here): https://app.asana.com/api/1.0/workspaces.
My C# code is as follows (abbreviated to relevant parts, and assume that ACCESS_TOKEN contains the access token I got from the token exchange endpoint):
HttpClient client = new HttpClient();
client.BaseAddress = "https://app.asana.com/api/1.0";
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", ACCESS_TOKEN);
client.DefaultRequestHeaders.Add("Accept", "application/json");
And then I use this HttpClient (named client) in the following function:
// Returns a list of the Asana workspace names for the logged in user.
private async Task<List<string>> GetWorkspacesAsync()
{
    List<string> namesList = new List<string>();
    // Send the HTTP Request and get a response.
    this.UpdateToken(); // Refreshes the token if needed using the refresh token.
    using (HttpResponseMessage response = await client.GetAsync("/workspaces"))
    {
        // Handle a bad (not ok) response.
        if (response.StatusCode != HttpStatusCode.OK)
        {
            //  !!!THIS KEEPS TRIGGERING WITH response.StatusCode AS 403 Forbidden!!!
            // Set up a stream reader to read the response.
            // This is for TESTING ONLY
            using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
            {
                // Extract the json object from the response.
                string content = reader.ReadToEnd();
                Debug.WriteLine(content);
            }
            throw new HttpRequestException("Bad HTTP Response was returned.");
        }
        // If execution reaches this point, the Http Response returned with code OK.
        // Set up a stream reader to read the response.
        using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
        {
            // Extract the json object from the response.
            string content = reader.ReadToEnd();
            JsonValue responseJson = JsonValue.Parse(content);
            foreach (JsonValue workspaceJson in responseJson["data"])
            {
                string workspaceName = workspaceJson["name"];
                Debug.WriteLine("Workspace Name: " + workspaceName);
                namesList.Add(workspaceName);
            }
        }
    }
    // I have other awaited interactions with app storage in here, hence the need for the function to be async.
    return namesList;
}