CURL с аутентификацией пользователя в С#
Я хочу сделать следующий запрос cURL в С#:
curl -u admin:geoserver -v -XPOST -H 'Content-type: text/xml' \
-d '<workspace><name>acme</name></workspace>' \
http://localhost:8080/geoserver/rest/workspaces
Я попытался использовать WebRequest:
string url = "http://localhost:8080/geoserver/rest/workspaces";
WebRequest request = WebRequest.Create(url);
request.ContentType = "Content-type: text/xml";
request.Method = "POST";
request.Credentials = new NetworkCredential("admin", "geoserver");
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>my_workspace</name></workspace>");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
WebResponse response = request.GetResponse();
...
Но я получаю сообщение об ошибке: (400) Плохой запрос.
Если я изменю учетные данные запроса и добавлю аутентификацию в заголовок:
string url = "http://localhost:8080/geoserver/rest/workspaces";
WebRequest request = WebRequest.Create(url);
request.ContentType = "Content-type: text/xml";
request.Method = "POST";
string authInfo = "admin:geoserver";
request.Headers["Authorization"] = "Basic " + authInfo;
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>my_workspace</name></workspace>");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
WebResponse response = request.GetResponse();
...
Затем я получаю: (401) Несанкционированный.
Мой вопрос: должен ли я использовать другой класс С#, такой как WebClient или HttpWebRequest, или мне нужно использовать привязки curl для .NET?
Все комментарии или рекомендации будут оценены.
Ответы
Ответ 1
Решение моего вопроса заключалось в изменении свойства ContentType. Если я изменю ContentType на
request.ContentType = "text/xml";
запрос работает в обоих случаях, если я также конвертирую authInfo в Base64String в последний пример, например, предложил Антон Гоголев.
Ответ 2
HTTP Общая аутентификация требует все после "Basic" для кодирования Base64, поэтому попробуйте
request.Headers["Authorization"] = "Basic " +
Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
Ответ 3
Использование:
request.ContentType = "application/xml";
request.Credentials = new NetworkCredential(GEOSERVER_USER, GEOSERVER_PASSWD);
также работает. Второй устанавливает аутентификационную информацию.
Ответ 4
Или, если вы хотите использовать HttpClient:
var authValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("admin:geoserver")));
try
{
var client = new HttpClient()
{
DefaultRequestHeaders = { Authorization = authValue }
};
string url = "http://{BASE_URL}";
client.BaseAddress = new Uri(url);
var content = new StringContent("<workspace><name>TestTestTest</name></workspace>",
Encoding.UTF8, "text/xml");
var response = await client.PostAsync($"/{PATH_TO_API}/", content);
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
Console.WriteLine(ex.Message);
}