[c#] HttpWebRequest using Basic authentication

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...

This question is related to c# authentication credentials webrequest

The answer is


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; 

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;

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!


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;
}

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


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.


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();

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");

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;

You can also just add the authorization header yourself.

Just make the name "Authorization" and the value "Basic BASE64({USERNAME:PASSWORD})"

String username = "abc";
String password = "123";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
httpWebRequest.Headers.Add("Authorization", "Basic " + encoded);

Edit

Switched the encoding from UTF-8 to ISO 8859-1 per What encoding should I use for HTTP Basic Authentication? and Jeroen's comment.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to authentication

Set cookies for cross origin requests How Spring Security Filter Chain works What are the main differences between JWT and OAuth authentication? http post - how to send Authorization header? ASP.NET Core Web API Authentication Token based authentication in Web API without any user interface Custom Authentication in ASP.Net-Core Basic Authentication Using JavaScript Adding ASP.NET MVC5 Identity Authentication to an existing project LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1

Examples related to credentials

git clone: Authentication failed for <URL> How to save username and password in Git? AWS : The config profile (MyName) could not be found Remove credentials from Git Configuring user and password with Git Bash SVN change username HttpWebRequest using Basic authentication Using cURL with a username and password? How do I find my host and username on mysql? How to Specify Eclipse Proxy Authentication Credentials?

Examples related to webrequest

Which versions of SSL/TLS does System.Net.WebRequest support? How do you send an HTTP Get Web Request in Python? Reasons for a 409/Conflict HTTP error when uploading a file to sharepoint using a .NET WebRequest? HttpWebRequest using Basic authentication Cannot send a content-body with this verb-type How to use WebRequest to POST some data and read response? How to get json response using system.net.webrequest in c#? How do I use WebRequest to access an SSL encrypted site using https? Cannot set some HTTP headers when using System.Net.WebRequest