How to Login to Website in C#

  1. Use the WebClient to Log Into a Website in C#
  2. Write a Script to Log Into a Website in C#
  3. Create a Script to Automate Selenium to Log Into a Website in C#
  4. Use the HttpClient to Log Into a Website in C#
How to Login to Website in C#

In this tutorial, you will learn and understand the optimized methods to login into the website programmatically in C#. It’s possible to auto login to the external website using ASP.NET C#, and in case the website uses HTTP POST to validate login, you can use the post method externally.

It is a general way to add the service reference to the C# project since Visual Studio automatically generates a proxy for you by calling the proxy class web server method. However, programmatic is the perfect way to call a web server and authenticate it.

Use the WebClient to Log Into a Website in C#

The best approach to programmatic login to a website is using WebClient to POST. A solid replacement for POST (as it is highly complex for entry-level developers) is the lower-level WebRequest and WebResponse classes.

Creating a login form is one of the two primary parts of this approach, and the second is to recover the Set-cookie header using the GET request. If your Set-cookie header as a Cookie you sent along with the GET request is recognized by the responding server, then it will identify you from now on only if the server is using a cookie-based authentication.

Use the following C# code for GET:

public static string HttpGet(string web_URI) {
  System.Net.WebRequest web_request = System.Net.WebRequest.Create(web_URI);

  // the following means no proxy for the website
  web_request.Proxy = new System.Net.WebProxy(ProxyString, true);

  System.Net.WebResponse web_response = web_request.GetResponse();

  System.IO.StreamReader stream_reader =
      new System.IO.StreamReader(web_response.GetResponseStream());

  return stream_reader.ReadToEnd().Trim();
}

Use the following C# code for SET:

public static string HttpPost(string web_URI, string web_para) {
  System.Net.WebRequest web_request = System.Net.WebRequest.Create(web_URI);
  web_request.Proxy = new System.Net.WebProxy(ProxyString, true);

  // add the following as you are doing the `POST`
  web_request.ContentType = "your_application/insert-the-form-rncoded-URL";
  web_request.Method = "POST";  // SET

  // it's important to know how many bytes you are transforming or sending to the server.
  // Remember | Post'ed Faked Forms should be `name=value&`
  byte[] sending_bytes = System.Text.Encoding.ASCII.GetBytes(web_para);
  web_request.ContentLength = sending_bytes.Length;

  System.IO.Stream web_stream = web_request.GetRequestStream();

  // you can push the bytes here
  web_stream.Write(sending_bytes, 0, sending_bytes.Length);
  web_stream.Close();

  System.Net.WebResponse web_response = web_request.GetResponse();
  if (web_response == null)
    return null;

  System.IO.StreamReader stream_reader =
      new System.IO.StreamReader(web_response.GetResponseStream());

  return stream_reader.ReadToEnd().Trim();
}

Form posts are easy to simulate as you can easily format your post data by doing something like the following:

field_1 = value_1 & field_2 = value_2

The example C# WebClient code of this method reflects the Scott Hanselman approach to login to a website using WebRequest.

Furthermore, the following C# code represents the approach created by Scott Hanselman to programmatically login into websites:

// the `web_URL` represents the `POST` URL instead of the `form` URL
// to access `form` URL, find the `action` attribute of the HTML's `form` tag
string web_URL =
    "http://www.examplewebsite.com/index.do?PageModule=UserAccess&Modification=UsersVerificationviaLogin";

string parameter_form = string.Format("example_format(email_address={0}&password={1})",
                                      "my_email_address", "my_password");

// create a header cookie
string header_cookie;

// create a request object from the `WebRequest`
WebRequest web_request = WebRequest.Create(web_URL);

// define its content type and method
web_request.ContentType =
    "yourC#application/x-www_address-form-encoded_url";  // or something like
                                                         // "application/x-www-form-urlencoded"
web_request.Method = "POST";  // as it's a request, so the method will be POST

// access the `parameter_form` to convert it into bytes (sending it to the server)
byte[] sending_bytes = Encoding.ASCII.GetBytes(parameter_form);
web_request.ContentLength = sending_bytes.Length;  // define its length

using (Stream web_stream = web_request.GetRequestStream()) {
  // for web requests or requests to the server for login
  web_stream.Write(sending_bytes, 0, sending_bytes.Length);
}

// create a `WebResponse` object to receive or understand the response from the corresponding server
WebResponse web_response = web_request.GetResponse();
header_cookie = web_response.Headers["Set-cookie"];  // `Set-cookie` as a web response header file

/*
    GET
*/

// define a source page and the `GET` web URL
string source_page;
string web_URL_get =
    "http://www.webpage_behind_the_login.com";  // mention the webpage behind the login form

// create a GET response
WebRequest web_request_get = WebRequest.Create(web_URL_get);
web_request_get.Headers.Add("Cookie", header_cookie);

// web_request_get.ContentLength = web_request.ContentLength;
WebResponse web_response_get = web_request_get.GetResponse();

using (StreamReader stream_reader_get = new StreamReader(web_response_get.GetResponseStream())) {
  source_page = stream_reader_get.ReadToEnd();
}

The following is the C# code you can copy/paste to your C# project and login to a website using WebClient. However, remember to use your own username and password and enter the website URL, as well as, don’t forget to mention the webpage your C# program will redirect you after a successful login.

using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.Collections.Specialized;

namespace test_login {
  // create a sub-class using `WebClient`
  public class CookieAwareWebClient : WebClient {
    // create a cookie container for web requests and web response
    private CookieContainer website_cookie = new CookieContainer();

    // overload using URI of the target web address
    protected override WebRequest GetWebRequest(Uri trg_web_add) {
      WebRequest tag_web_request = base.GetWebRequest(trg_web_add);
      if (tag_web_request is HttpWebRequest) {
        (tag_web_request as HttpWebRequest).CookieContainer =
            website_cookie;  // generate a proper request to the server
      }
      return tag_web_request;
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      // create a new user
      var new_user = new CookieAwareWebClient();

      // base address of the corresponding webpage (for login)
      new_user.BaseAddress = @"https://www.example_website/some_page/login/url_address/";

      // create a variable that carries the user information
      var user_info = new NameValueCollection();
      user_info.Add("username", "your_username");  // username or mail address
      user_info.Add("password", "your_password");  // password

      // upload the user information to the webpage
      new_user.UploadValues("login_page.php", "POST", user_info);

      // successfully login can request the pages, following
      string source_html = new_user.DownloadString("website_homepage.php");
    }
  }
}

Output:

username: your_username
password: your_password

[redirect the user to the `index.php` after a successful login]

Another interesting idea is to modify this approach by setting a CookieContainer object on the GetWebRequest method after overriding it by creating a class that derives from WebClient. A single or the same CookieContainer instance can handle cookie management by default.

Write a Script to Log Into a Website in C#

The login procedure for each website can be unique and requires different protocols, as logging into websites programmatically is tightly coupled with how the websites implement their login procedures. You need to understand the process and write your requests and responses (to and from the server) accordingly.

Writing an incredibly complicated and fragile script to pass the website’s procedures is not an easy job, but doing so can enhance the security and effectiveness of your application. Furthermore, it can help to switch off the AllowAutoRedirect and set both POST and GET requests to the same user agent by doing something like:

request.UserAgent = UserAgent;

// to eliminate any redirection to other website or webpage
request.AllowAutoRedirect = false;

Some websites send cryptic URL-encoded return values as you attempt to log in, and if the server notices something misses, it will throw something like HTTP/1.1 400 Bad Request, or it can be a 200 response from the server with an error message buried somewhere inside. You must collect the right values and pass them in an HttpWebRequest object so the server wouldn’t know the difference and let you log in.

using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.IO;
// using System.Collections.Specialized;

namespace test_login {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e) {
      string user_name = UsernameBox.Username;              // textbox that contains the user name
      string user_password = PasswordBoxPassword.Password;  // textbox that contains the password

      // HTML IDs or important user information to perform a successful login against a specific
      // user
      string login_user_name = textBox1.Text;      // username
      string login_user_password = textBox2.Text;  // password

      // submit info for a successful login
      string login_submit_info = textBox3.Text;  // login submit

      // define the website or webpage connection parameters
      string post_method = "POST";  // `POST` method for web_request
      string type_webcontent = @"c_sharp-application/encoded_url-www-form";
      string string_login = login_user_name + "=" + user_name + "&" + login_user_password + "=" +
                            user_password + "&" + login_submit_info;
      CookieContainer container_cookie = new CookieContainer();
      HttpWebRequest web_request;

      web_request = (HttpWebRequest)WebRequest.Create(
          "http://www.example_url.com/login_page/");  // or insert the `url` string that contains
                                                      // the valid website URL
      web_request.CookieContainer = container_cookie;
      web_request.Method = post_method;  // for web request
      web_request.ContentType = type_webcontent;
      web_request.KeepAlive = true;

      using (Stream web_stream_request = web_request.GetRequestStream())

          // generate a proper web request
          using (StreamWriter writer = new StreamWriter(web_stream_request)) {
        writer.Write(string_login, user_name, user_password);
      }

      using (var web_stream_response = web_request.GetResponse().GetResponseStream()) using (
          var web_response_reader = new StreamReader(web_stream_response)) {
        var user_check = web_response_reader.ReadToEnd();
        Console.WriteLine(user_check);  // the result
      }

      MessageBox.Show("Successful login to website!");
    }
  }
}

Output:

Successful login to website!

Create a Script to Automate Selenium to Log Into a Website in C#

As writing a manual script can be frustrating, creating a script to automate selenium.WebDriver can be a valid option to log in to a website in C# programmatically. It enables you to throw your requests normally by handling all the juggling so that you can pull valid cookies out.

It’s important to understand selenium to optimize your code; for example, it works great for logging into azure to get credits which makes writing scripts incredibly short. However, as it’s missing the CookieContainer exp_cookie = new CookieContainer(); which means it’s not suitable for website supports CookieContainer.

// Install `Selenium.WebDriver` NuGet Package
// Install `Selenium.WebDriver.ChromeDriver` NuGet Package

using System;
using System.Windows.Forms;
using System.Net;
// using System.Net.Http;
using System.IO;
// using System.Collections.Specialized;

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

namespace login_website {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e) {
      // run selenium | starts from...
      ChromeDriver chrome_driver = new ChromeDriver(
          @"chromedriver_win32");  // install the selenium chrome web driver for `ChromeDriver`
      chrome_driver.Url = @"https://fif.com/login";
      chrome_driver.Navigate();
      IWebElement web_element = chrome_driver.FindElementById(
          "user_name");  // install selenium web driver to use `FindElementById()` method
      web_element.SendKeys("...");
      web_element = chrome_driver.FindElementById("user_password");
      web_element.SendKeys("...");
      web_element = chrome_driver.FindElementByXPath(
          @"//*[@id=""main""]/div/div/div[2]/table/tbody/tr/td[1]/div/form/fieldset/table/tbody/tr[6]/td/button");
      web_element.Click();

      CookieContainer cookie_container = new CookieContainer();

      // get the cookies from the website
      foreach (OpenQA.Selenium.Cookie web_cookie in chrome_driver.Manage().Cookies.AllCookies) {
        string user_name = web_cookie.Name;
        string user_value = web_cookie.Value;
        cookie_container.Add(
            new System.Net.Cookie(user_name, user_value, web_cookie.Path, web_cookie.Domain));
      }

      // generate a proper web request
      HttpWebRequest http_web_request = (HttpWebRequest)HttpWebRequest.Create(
          "https://example.com/web_content/com_example/web_tools/page_capacity/login_values/");  // or something like "https://fif.com/components/com_fif/tools/capacity/values/"
      http_web_request.CookieContainer = cookie_container;
      http_web_request.Method = "POST";
      http_web_request.ContentType = "application/x-www-form-urlencoded";

      StreamWriter stream_writer = new StreamWriter(http_web_request.GetRequestStream());
      stream_writer.Write("feeds=35");
      stream_writer.Close();

      WebResponse web_response = http_web_request.GetResponse();
      string response_imp =
          new System.IO.StreamReader(web_response.GetResponseStream()).ReadToEnd();
    }
  }
}

Output:

[redirect the user to the `index.php` after a successful login]

* or

[shows an error for wrong username or password for invalid user]

It does not require a Selenium server to automate the browser. It bypasses the JavaScript sandbox using native OS-level events to manipulate the browser.

Furthermore, it contains the .NET bindings for the concise and object-based Selenium WebDriver API.

Selenium features a bundle of different software tools, each with a different approach to supporting browser automation. It offers highly flexible tools for locating and manipulating elements within a browser and supports automation for multiple browser platforms.

Use the HttpClient to Log Into a Website in C#

It can help you access the actual login response as the status code for redirect is 3**; you must disable redirection with HttpClient. Send the credentials to request the URL using the HTTP verb request method (or it can be the POST method in most cases).

It is always easy to implement a login method based on the cookies the server expects to receive from the logged-in user, and this information is based on the data the set-cookie header contains.

You can use the GET and POST methods in HttpClient to log in to a website, as the GET includes no HTTP body. With a POST, the data moves from the QueryString into the HTTP body.

The user credentials or the data you will pass will be passed via parameters, and the rest will be hard-coded. Most importantly, the key-value pair instance (KeyValuePair<string, string>) represents the specified sequence of form data that can help you programmatically log in to the website.

Sometimes, it can happen that only user-specified data is required, and it’s an essential step for you to request the website and parse HTML using AngleSharp or any similar method if the website requires you to include hidden fields from the login page.

In conclusion, the resulting sequence with keys and values (nullable strings) is then passed to the FormUrlEncodedContent constructor (it expects the keys and values of the sequence to be nullable strings).

// try not to change the entry point of this C# code
// it's important to remember that the `website_login.Program.Main` in your C# project is the entry
// point of this C# program. changing the entry point can lead to many difficulties and logical or
// syntax errors

using System;
using System.Net;
using System.IO;

namespace website_login {
  public class Program {
    public static void Main(string[] args) {
      var add_primary = new Uri("https://www.example_website.com/");
      var container_cookie = new CookieContainer();  // for web request

      // generate a proper web request | special HTTP implementation of the `WebRequest` class
      HttpWebRequest post_request_web =
          (HttpWebRequest)HttpWebRequest.Create("https://www.example_website.com/");
      post_request_web.CookieContainer = container_cookie;

      /*
       * setting the agent (user_agent) and accepting the header values
       * these are important to simulate a real web browser
       */
      post_request_web.UserAgent =
          "Chrome/5.3 (Windows Professional 11.2; WOW32) Chrome/45.0.2454.101";  // change it with
                                                                                 // respect to your
                                                                                 // platform, OS,
                                                                                 // and browser
      post_request_web.Accept =
          "text_type/html,c_sharp_application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";  // set values

      Console.WriteLine("[response from the server...]");
      Console.WriteLine();

      // generate a proper web response
      using (WebResponse get_response_web = post_request_web.GetResponse()) {
        // to read the response from the web server
        using (StreamReader stream_reader =
                   new StreamReader(get_response_web.GetResponseStream())) {
          Console.WriteLine(stream_reader.ReadToEnd());  // display
        }
      }

      post_request_web = (HttpWebRequest)HttpWebRequest.Create("https://www.example_website.com/");

      // setting `container_cookie` as a cookie container object
      post_request_web.CookieContainer = container_cookie;

      post_request_web.UserAgent =
          "Chrome/5.3 (Windows Professional 11.2; WOW32) Chrome/45.0.2454.101";  // change it with
                                                                                 // respect to your
                                                                                 // platform, OS,
                                                                                 // and browser
      post_request_web.Accept =
          "text_type/html,c_sharp_application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";  // set values

      post_request_web.Method = "POST";  // POST method because of web request
      post_request_web.ContentType =
          "application/x-www-form-urlencoded";  // it is a standard content type

      // the `user_infomration` variable contains the username and password of a user for login
      string user_information =
          string.Format("username={0}&password={1}", "your_username", "your_password");

      // encode the user information to send it to the web server
      byte[] _web_bytes = System.Text.Encoding.UTF8.GetBytes(user_information);

      post_request_web.ContentLength = _web_bytes.Length;

      using (Stream web_stream_user_info = post_request_web.GetRequestStream()) {
        web_stream_user_info.Write(_web_bytes, 0, _web_bytes.Length);
        web_stream_user_info.Close();
      }

      Console.WriteLine("[response form the server on user login...]");
      Console.WriteLine();

      using (WebResponse web_response_dll = post_request_web.GetResponse()) {
        // to read the response from the web server
        using (StreamReader stream_reader_dll =
                   new StreamReader(web_response_dll.GetResponseStream())) {
          Console.WriteLine(stream_reader_dll.ReadToEnd());  // display
        }
      }

      //....
    }
  }
}

Output:

[response from the server...]

... // some response from the website
*response from the `streamreader`*

[response from the server on user login...]
// response from the server or website after the first login attempt

The instance of the FormUrlEncodedContent constructor is the primary content of the POST request in the PostAsync call, and after making this call, the next step is to parse the set-cookie headers from the HTTP response. It is always a hard choice to find any good NuGet package in the .NET class library, and that is why parsing is the better way by using a regular expression.

Check the response cookie to detect a failed login, check the response’s status code from the server, or parse the HTML content returned from the server. Calling the LoginAsync before downloading the requested page is always a great option to retrieve or return the login cookies for you to use for the request to the server.

If you find no built-in GetStringAsync method overload with a parameter for cookies, create an extension method yourself, as you will observe its creation in the following C# code. Before using the SendAsync method for sending the request (generated HTTP request), you must combine all the cookies into a single cookie header.

It is an option if you want to disable the automatic redirection feature of the HttpClient if the login response status code requires redirection. It can be done with the HttpClient instance since it is possible to do this with the IHttpClientFactory by passing the option when registering the HttpClient for dependency injection.

As there is no built-in functionality in HttpClient or .NET, in general, to programmatically log in to a website, you must manually perform all the steps, and it can be possible that each time the process is different. Because the authentication or login data is set on a cookie, set the CookieContainer to perform a login in a standard FormsAuthentication website using the HttpClient.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

Related Article - Csharp Authentication