.NET - using HTTP services on the server (Domino) with forms-based authentication

I am writing a utility in C # (.NET) that will use HTTP to request data from a Domino web server.

However, this server uses forms-based authentication rather than basic HTTP authentication.

I am trying to figure out how to encode HTTP GETS / POSTS with a server on which forms-based authentication is installed.

I tried every Google request that I can think of, but as soon as the words “forms-based authentication” are entered in the request, all the results refer only to the implementation of the server part of the service, usually in ASP.NET or Sharepoint, without which or any results on the consumption of such services by the client.

I saw Java code from a related question suggested here in Stack Overflow, but finding the relevant parts in foreign APIs in another language would be an adventure. If there is a sample .NET code or documentation, I would really appreciate it.

+4
source share
3 answers

I'm sure someone can give a better answer, but thinking about it, I would suggest that your server hosting the web service has some kind of login mechanism to establish that you are authenticated. So my approach would be to first publish the login page, accept the forms authentication cookie, and continue with all subsequent requests that you want to make. All subsequent requests will already have authentication cookies in them.

+2
source

Thanks to everyone who provided advice.

I want to share the reverse code that I developed in case it helps someone else. Although written specifically for the Domino server, it is very easy to change it for the actual field names in the column of any cookie-based authentication server.

To use the class:

  • Create a DominoHttpSession, passing it all the necessary properties, such as server name, username and password.
  • Call authentication
  • Call Get or GetXml as many as needed
  • In the end, get rid of DominoHttpSession, although it does not have an official closure, since HTTP is technically stateless.

Limitations:

This simple version will fail to execute cookie time. He is not trying to determine if the entry is successful or not.

using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Xml.Linq; namespace WebDomino { /// <summary> /// A stateful (authenticated) session with a Domino server. Current version only supports /// forms based authentication, and does not permit bypassing authentication. /// </summary> public class DominoHttpSession { /// <summary> /// Username with which to authenticate to the Domino server, must be a legal web user name. /// </summary> public string UserName { set; get; } /// <summary> /// Web password of the authenticating account. /// </summary> public string Password { set; get; } /// <summary> /// The server on which the session will exist. At this time, all connections must use /// the same server. Untested but probably will work: switching server name before establishing /// a connection, as long as the authentication cookies are shared. /// </summary> public string ServerHostName { set; get; } /// <summary> /// The session cookies. Provided in case client code wants to analyze cookie content, but /// more likely only used internally to hold the authentication cookie from the server. /// </summary> public CookieContainer Cookies { get { return cookies; } } private CookieContainer cookies = new CookieContainer(); /// <summary> /// Sends an HTTP GET to the server, expecting an XML response. /// </summary> /// <param name="url">The full url to GET; proper syntax is the responsibility of the caller.</param> /// <returns>The XElement representing the returned XML text</returns> public XElement GetXml(string url) { return XElement.Parse(Get(url)); } public string Get(string url) { var request = (HttpWebRequest)WebRequest.Create(url); request.CookieContainer = cookies; request.Method = "GET"; using (var responseStream = request.GetResponse().GetResponseStream()) using (var reader = new StreamReader(responseStream)) { var result = reader.ReadToEnd(); return result; } } /// <summary> /// Must be called to establish the session with the server. /// </summary> public void Authenticate() { ServicePointManager.Expect100Continue = false; var request = (HttpWebRequest)WebRequest.Create(String.Format("http://{0}//names.nsf?Login", ServerHostName)); request.CookieContainer = cookies; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; using (var requestStream = request.GetRequestStream()) using (var writer = new StreamWriter(requestStream)) { writer.Write("Username={0}&Password={1}", UserName,Password); } using (var responseStream = request.GetResponse().GetResponseStream()) using (var reader = new StreamReader(responseStream)) { var result = reader.ReadToEnd(); // Success is assumed here--in production code it should not be } } public ViewReader GetViewReader(string dbPath, string viewName) { return new ViewReader(this) { DbPath = dbPath, View = viewName }; } } } 
+2
source

During session-based authentication (what you call "form-based authentication"), Domino generates a so-called LTPA token (cookie) for further user authentication.

The easiest way to get this is to emulate the browser / user by sending the login form with the necessary form data to the server, extracting the LTPA cookie from the server response and using it in subsequent requests. You can use, for example, WatiN to simplify this.

Or you can calculate the value of the cookie that creates it yourself. The format, ... of the LTPA cookie is easy to find through Google, but it is not trivial and you need some data from the server.

If you do this on a server, you know the administrator, you can ask him to add a website rule that allows basic authentication to be used for a subset of requests, while session-based authentication is used for the rest of the website.

+1
source

Source: https://habr.com/ru/post/1389335/


All Articles