cURL with user authentication in C#
I want to do the following cURL request in c#:
curl -u admin:geoserver -v -XPOST -H 'Content-type: text/xml' \
-d '<workspace><name>acme</name></workspace>' \
http://localhost:8080/geoserver/rest/workspaces
I have tried using a 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();
...
But I get an error: (400) Bad request.
If I change the request credentials and add the authentication in the header:
string url = "http://localhost:8080/geoserver/rest/workspaces";
WebRequest request = W开发者_Python百科ebRequest.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();
...
Then I get: (401) Unauthorised.
My question is: Should I use another C# class like WebClient or HttpWebRequest or do I have to use the curl bindings for .NET?
All comments or guidance would be appreciated.
HTTP Basic authentication requies everything after "Basic " to be Base64-encoded, so try
request.Headers["Authorization"] = "Basic " +
Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
The solution to my question was changing the ContentType property. If I change the ContentType to
request.ContentType = "text/xml";
the request works in both cases, if I also convert the authInfo to a Base64String in the last example like Anton Gogolev suggested.
Using:
request.ContentType = "application/xml";
request.Credentials = new NetworkCredential(GEOSERVER_USER, GEOSERVER_PASSWD);
also works. The second sets authentication information.
Or, if you want to use 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);
}
精彩评论