I need to use an API key (with Basic authentication values) when calling third-party APIs on another (internal) server.
With Net6, ServiceStack/6.1.0 and ServiceStack.HttpClient/6.1.0, the following works:
protected virtual string Send(string relativeUrl, string method, string? body, string? idempotencyKey)
{
var url = _apiUrl.CombineWith(relativeUrl);
var response = url.SendStringToUrl(method: method, requestBody: body, requestFilter: req =>
{
InitRequest(req, method);
});
return response;
}
protected virtual void InitRequest(HttpRequestMessage req, string method)
{
req.Headers.Add("Accept", MimeTypes.Json);
req.Headers.Authorization = new AuthenticationHeaderValue("Basic", "c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz");
if (method == HttpMethods.Post || method == HttpMethods.Put || method == HttpMethods.Patch)
{
req.Headers.Add("ContentType", MimeTypes.Json);
}
}
In a new project with Net6, ServiceStack/6.2.1 and ServiceStack.HttpClient/6.2.1, I changed the above code, because HttpWebRequest is officially deprecated, to the code below. Unfortunately, it does not work, receiving 403 Forbidden responses.
protected virtual string Send(string relativeUrl, string method, string? body, string? idempotencyKey)
{
var url = _apiUrl.CombineWith(relativeUrl);
// This is not working with Net6 HttpClient, so use version below
// var response = url.SendStringToUrl(method: method, requestBody: body, requestFilter: req =>
// {
// InitRequest(req, method, idempotencyKey);
// });
// This works when API does not require Basic authentication
//var response = url.SendStringToUrl(method: method, requestBody: body, contentType: MimeTypes.Json, accept: MimeTypes.Json);
// This does not work when API requires Basic authentication
var response = url.SendStringToUrl(method: method, contentType: MimeTypes.Json, accept: MimeTypes.Json,
requestBody: body, requestFilter: req =>
req.AddApiKeyAuth("Basic c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz"); // test also failed
req.With(c => ConfigHttpRequest(method))
);
return response;
}
protected virtual HttpRequestConfig ConfigHttpRequest(string method)
{
HttpRequestConfig config = new();
config.Accept = MimeTypes.Json;
if (method == HttpMethods.Post || method == HttpMethods.Put || method == HttpMethods.Patch)
{
config.ContentType = MimeTypes.Json;
}
// Cannot use SetAuthBasic(), because value is only available as an encoded Base64 UTF8 string
//config.SetAuthBasic("Basic", "c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz");
// This did not work
config.Authorization = new NameValue(name: "Basic", value: "c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz");
// Neither did this work (similar to approach used in ServiceStack/6.1.0 project)
var token = new AuthenticationHeaderValue("Basic", "c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz");
config.AddHeader("Authorization", token.ToString());
return config;
}
I have tried tracing the execution, and the one thing I noticed is that in HttpUtils.HttpClient the httpReq object has a null value for Authorization.
For completeness:
Using curl, an example of a working query using Basic authentication is
curl -X GET "http://fx.data.local:8035/api/pricing/v1/latest" `
-H "accept: */*" -H "Authorization: Basic c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz"
In Postman, the following Auth settings work:
Type: API Key
Key: Authorization
Value: Basic c2NcmlAYWxEtY2gtYWRmczpjaGVteUA2MzMz
Add to: Header
Any ideas how to solve myproblem?