Reputation: 2567
I'm trying to go through an authentication request that mimics the "basic auth request" we're used to seeing when setting up IIS for this behavior.
The URL is: https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(warning: https!)
This server is running under UNIX and Java as application server.
This is the code I use to connect to this server:
CookieContainer myContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
request.Credentials = new NetworkCredential(xxx,xxx);
request.CookieContainer = myContainer;
request.PreAuthenticate = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
(I copied this from another post on this site). But I receive this answer from the server:
The underlying connection was closed: An unexpected error occurred on a send.
I think I tried every possible task my knowledge on C# has to offer me, but nothing...
Upvotes: 185
Views: 467785
Reputation: 2955
Here's how to do a Http Basic Auth string in C#
string username = "user";
string password = "pass";
var basicAuthBytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"{username}:{password}");
var authHeaderValue = $"Basic {System.Convert.ToBase64String(basicAuthBytes)}";
Upvotes: 1
Reputation: 4591
You can also just add the authorization header yourself.
Just make the name "Authorization" and the value "Basic BASE64({USERNAME:PASSWORD})"
var username = "abc";
var password = "123";
string encoded = System.Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1")
.GetBytes(username + ":" + password));
httpWebRequest.Headers.Add("Authorization", "Basic " + encoded);
Switched the encoding from UTF-8 to ISO 8859-1 per What encoding should I use for HTTP Basic Authentication? and Jeroen's comment.
Upvotes: 370
Reputation: 29
One reason why the top answer and others wont work for you is because it is missing a critical line. (note many API manuals leave out this necessity)
request.PreAuthenticate = true;
Upvotes: -1
Reputation: 325
First thing, for me ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 worked instead of Ssl3.
Secondly, I had to send the Basic Auth request along with some data (form-urlencoded). Here is the complete sample which worked for me perfectly, after trying many solutions.
Disclaimer: The code below is a mixture of solutions found on this link and some other stackoverflow links, thanks for the useful information.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
String username = "user_name";
String password = "password";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
//Form Data
var formData = "var1=val1&var2=val2";
var encodedFormData = Encoding.ASCII.GetBytes(formData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("THE_URL");
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.ContentLength = encodedFormData.Length;
request.Headers.Add("Authorization", "Basic " + encoded);
request.PreAuthenticate = true;
using (var stream = request.GetRequestStream())
{
stream.Write(encodedFormData, 0, encodedFormData.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Upvotes: 6
Reputation: 957
The following construction was not working correctly for me:
request.Credentials = new NetworkCredential("user", "pass");
I have used CredentialCache
instead:
CredentialCache credentialCache = new CredentialCache
{
{
new Uri($"http://{request.Host}/"), "Basic",
new NetworkCredential("user", "pass")
}
};
request.Credentials = credentialCache;
However, if you would like to add multiple basic auth credentials (for example if there is redirection that you are aware of) you can use following function that I have made:
private void SetNetworkCredential(Uri uriPrefix, string authType, NetworkCredential credential)
{
if (request.Credentials == null)
{
request.Credentials = new CredentialCache();
}
if (request.Credentials.GetCredential(uriPrefix, authType) == null)
{
(request.Credentials as CredentialCache).Add(uriPrefix, authType, credential);
}
}
I hope it will help somebody in the future.
Upvotes: 1
Reputation: 23078
For those using RestSharp, it might fail when using SimpleAuthenticator (possibly due to not using ISO-8859-1 behind the scene). I managed to get it done by explicitly sending Basic Authentication headers:
string username = "...";
string password = "...";
public IRestResponse GetResponse(string url, Method method = Method.GET)
{
string encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes($"{username}:{password}"));
var client = new RestClient(url);
var request = new RestRequest(method );
request.AddHeader("Authorization", $"Basic {encoded}");
IRestResponse response = client.Execute(request);
return response;
}
var response = GetResponse(url);
txtResult.Text = response.Content;
Upvotes: 9
Reputation: 349
Following code will solve json response if there Basic Authentication and Proxy implemented.Also IIS 7.5 Hosting Problm will resolve.
public string HttpGetByWebRequ(string uri, string username, string password)
{
//For Basic Authentication
string authInfo = username + ":" + password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
//For Proxy
WebProxy proxy = new WebProxy("http://10.127.0.1:8080", true);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.Accept = "application/json; charset=utf-8";
request.Proxy = proxy;
request.Headers["Authorization"] = "Basic " + authInfo;
var response = (HttpWebResponse)request.GetResponse();
string strResponse = "";
using (var sr = new StreamReader(response.GetResponseStream()))
{
strResponse= sr.ReadToEnd();
}
return strResponse;
}
Upvotes: 4
Reputation: 560
The spec can be read as "ISO-8859-1" or "undefined". Your choice. It's known that many servers use ISO-8859-1 (like it or not) and will fail when you send something else.
For more information and a proposal to fix the situation, see http://greenbytes.de/tech/webdav/draft-reschke-basicauth-enc-latest.html
Upvotes: 2
Reputation: 3901
If you can use the WebClient
class, using basic authentication becomes simple:
var client = new WebClient {Credentials = new NetworkCredential("user_name", "password")};
var response = client.DownloadString("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
Upvotes: 35
Reputation: 2567
I finally got it!
string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
WebRequest request = WebRequest.Create(url);
request.Credentials = GetCredential();
request.PreAuthenticate = true;
and this is GetCredential()
private CredentialCache GetCredential()
{
string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(ConfigurationManager.AppSettings["ead_username"], ConfigurationManager.AppSettings["ead_password"]));
return credentialCache;
}
YAY!
Upvotes: 70
Reputation: 13690
Try this:
System.Net.CredentialCache credentialCache = new System.Net.CredentialCache();
credentialCache.Add(
new System.Uri("http://www.yoururl.com/"),
"Basic",
new System.Net.NetworkCredential("username", "password")
);
...
...
httpWebRequest.Credentials = credentialCache;
Upvotes: 12