Search code examples
c#cookieshttpclient

401 when trying to use an authentication cookie for subsequent HttpClient Request


I'm trying to use a 3rd party API, SmartFile, to retrieve an activity log. Their documentation is a shell script. I'm trying to translate to C# and while I'm able to retrieve the cookie when I try to use the cookie to retrieve the activity, I still receive a 401.

var baseUrl = "https://example.smartfile.com/api/";
var clientId = "clientId";
var clientSecret = "clientSecret";

var cookies = new CookieContainer();
var handler = new HttpClientHandler()
{
    CookieContainer = cookies,
    UseCookies = true,
    AllowAutoRedirect = true
};
        
var creds = Convert.ToBase64String(
    Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}"));

var httpClient = new HttpClient(handler) {BaseAddress = new Uri(baseUrl)};
httpClient.DefaultRequestHeaders.Authorization 
   = new AuthenticationHeaderValue("Basic", creds);
        
var sessionRequestUrl = "2/session/";
var sessionResponse = await httpClient.PostAsync(sessionRequestUrl, null); // 201
sessionResponse.EnsureSuccessStatusCode();
var cookieCount = cookies.Count;//2
var cookie = sessionResponse.Headers.FirstOrDefault(h => h.Key == "Set-Cookie");
        
var requestUrl = $@"3/activity/search?date={DateTime.Now:yyyy-MM-dd}";
var request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
request.Headers.TryAddWithoutValidation("Cookie", cookie.Value);
var response = await httpClient.SendAsync(request); // 401

I've tried httpClient.DefaultRequestHeaders.Clear(); before the 2nd call.


Solution

  • Can you please try simply following below, replacing your last part of the code, httpClient handles cookies automatically using CookieContainer in the subsequent call. https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.usecookies?view=net-8.0 it is true by default.

    var httpClient = new HttpClient(handler) {BaseAddress = new Uri(baseUrl)};
    httpClient.DefaultRequestHeaders.Authorization 
       = new AuthenticationHeaderValue("Basic", creds);
    var sessionRequestUrl = "2/session/";
    var sessionResponse = await httpClient.PostAsync(sessionRequestUrl, null); // 201
    sessionResponse.EnsureSuccessStatusCode();
    var requestUrl = $@"3/activity/search?date={DateTime.Now:yyyy-MM-dd}";
    response = await client.GetAsync(requestUrl);