How to use curl basic auth in C#
To use curl basic auth in C#, pass -u username:password in the command you give Curl.ExecuteAsync, or call .WithBasicAuth(username, password) on CurlRequestBuilder. CurlDotNet base64-encodes the credentials into an Authorization: Basic header exactly as curl does.
dotnet add package CurlDotNet
The curl command
using CurlDotNet;
var result = await Curl.ExecuteAsync(
"curl -u user:passwd https://httpbin.org/basic-auth/user/passwd");
Console.WriteLine(result.StatusCode); // 200
--basic is accepted and is the default for -u. As in curl, -u splits at the first colon, so a password may itself contain colons, and credentials written into the URL (https://user:passwd@host/) are sent as Basic too. -n / --netrc-file reads them from a .netrc file; see config files and variables.
API keys as the user name
Some APIs, Stripe for example, take the API key as the user name with an empty password. The trailing colon works the same as in curl:
using CurlDotNet;
var result = await Curl.ExecuteAsync("curl -u sk_test_123: https://httpbin.org/headers");
Console.WriteLine(result.Body); // "Authorization": "Basic c2tfdGVzdF8xMjM6"
The fluent builder
using CurlDotNet.Core;
var result = await CurlRequestBuilder
.Get("https://httpbin.org/basic-auth/user/passwd")
.WithBasicAuth("user", "passwd")
.ExecuteAsync();
Console.WriteLine(result.IsSuccess);
Or, with LibCurl, set it once for all requests:
using CurlDotNet.Lib;
using var curl = new LibCurl();
curl.WithBasicAuth("user", "passwd");
var result = await curl.GetAsync("https://httpbin.org/basic-auth/user/passwd");
Console.WriteLine(result.StatusCode);
Digest, NTLM and Negotiate
Challenge-response schemes use the same -u value plus a scheme flag:
using CurlDotNet;
var result = await Curl.ExecuteAsync(
"curl --digest -u user:passwd https://httpbin.org/digest-auth/auth/user/passwd");
Console.WriteLine(result.StatusCode); // 200
--ntlm, --negotiate and --anyauth are also accepted. Digest, NTLM (v1 and v2) and --anyauth are negotiated by CurlDotNet itself in pure C#, the way curl does it: the first request goes out without credentials (a POST or PUT as a Content-Length: 0 probe), the server’s challenge picks the scheme (--anyauth prefers Digest, then NTLM, then Basic), and no Basic header is ever sent when a challenge scheme was asked for. They behave the same on every platform. Only --negotiate (Kerberos/SPNEGO) relies on the platform’s own support.
Authorization headers, --oauth2-bearer and URL credentials are not forwarded to a different host when -L follows a redirect, unless you add --location-trusted.
When the credentials are wrong
A 401 does not throw. Check result.StatusCode or call result.EnsureSuccess(), which throws CurlDotNet.Core.CurlHttpException for any non-2xx status. With -f, the 401 throws CurlHttpReturnedErrorException (exit code 22) instead. When Digest or NTLM negotiation itself cannot complete (for example the server offers no scheme you allowed), CurlAuthErrorException (exit code 94) is thrown.
Security notes
- Prefer HTTPS: Basic credentials are only base64-encoded, not encrypted.
- Read secrets from configuration or the environment. The parser expands
$NAMEoutside single quotes, as a shell would, so-u "$API_USER:$API_PASS"works when both variables are set (-u '$API_USER:$API_PASS'would send the text literally). CurlResult.Commandcontains the credentials; do not log it.