InContext
InContext

Reputation: 2501

HttpClient calling API doesnt not pass cookie auth

Trying to call an API from a controller using HttpClient and the API does not recognize the user as authenticated and logged in. When calling the API from JS I have no issue. I noticed the HttpClient was only sending via HTTP 1.1 and so I upgraded to 2.0 settings the DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER flag but this made no difference. I have tried all combinations of the HttpClientHandler properties including UseCookies and the request is never authenticated.

        using (var handler = new HttpClientHandler {UseDefaultCredentials = true})
        {
            using (var httpClient = new HttpClient(handler))
            {
                var response = httpClient.GetStringAsync(new Uri($"https://localhost:64366/api/")).Result;
            }
        }

Will move to token based auth in the future but for now would like to understand why there is a difference between calling the API from C# vs JS. This is all HTTPS on localhost using asp net core 2.2.

Upvotes: 0

Views: 2552

Answers (1)

Alexander
Alexander

Reputation: 9632

Difference between JS and C# is that browsers attach cookies automatically to requests and you have to attach cookies manually in C# as juunas mentioned.

To obtain and use authentication cookie you may use the following pattern

CookieContainer cookies = new CookieContainer(); //this container saves cookies from responses and send them in requests
var handler = new HttpClientHandler
{
    CookieContainer = cookies
};

var client = new HttpClient(handler);

string authUrl = ""; //your auth url
string anyUrl = ""; //any url that requires you to be authenticated

var authContent = new FormUrlEncodedContent(
    new List<KeyValuePair<string, string>> {
        new KeyValuePair<string, string>("login", "log_in"),
        new KeyValuePair<string, string>("password", "pass_word")
        }
    );

//cookies will be set on this request
HttpResponseMessage auth = await client.PostAsync(authUrl, authContent);
auth.EnsureSuccessStatusCode(); //retrieving result is not required but you will know if something goes wrong on authentication

//and here retrieved cookies will be used
string result = await client.GetStringAsync(anyUrl);

Upvotes: 3

Related Questions