.NET - использование HTTP-сервисов на сервере (Domino) с аутентификацией на основе форм - PullRequest
4 голосов
/ 04 января 2012

Я пишу утилиту на C # (.NET), которая будет использовать HTTP для запроса данных с веб-сервера Domino.

Однако этот сервер использует аутентификацию на основе форм, а не простую аутентификацию HTTP.

Я пытаюсь выяснить, как написать код для выполнения HTTP GETS / POSTS на сервере с аутентификацией на основе форм.

Я перепробовал каждый запрос Google, который мог придумать, но как только появились слова«Проверка подлинности на основе форм» содержится в запросе, все результаты относятся только к реализации службы на стороне сервера, обычно в ASP.NET или Sharepoint, без результатов о потреблении таких служб на стороне клиента.

Я видел код Java из соответствующего вопроса, предложенного здесь в Stack Overflow, но поиск соответствующих частей в сторонних API на другом языке будет приключением.Если есть пример кода или документации .NET, я был бы очень признателен.

Ответы [ 3 ]

2 голосов
/ 08 января 2012

Спасибо всем, кто предоставил подсказки.

Я хочу поделиться разработанным мною кодом на случай, если он кому-нибудь поможет.Хотя он написан специально для сервера Domino, его очень легко изменить для фактических имен полей в сообщении любого сервера аутентификации на основе файлов cookie.

Чтобы использовать класс:

  1. Создайте DominoHttpSession, передав ему все необходимые свойства, такие как имя сервера, имя пользователя и пароль.
  2. Call Authenticate
  3. Вызовите Get или GetXml столько, сколько требуется
  4. В конце концов избавьтесь от DominoHttpSession, хотя у него нет формального закрытия, так как HTTP технически не имеет состояния.

Ограничения:

Эта простая версия завершится с ошибкой тайм-аута cookie.Он не пытается определить, был ли вход успешным или нет.

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 голосов
/ 04 января 2012

Я уверен, что кто-то может дать лучший ответ, но подумав об этом, я бы предположил, что на вашем сервере, на котором размещается веб-служба, есть какой-то механизм входа в систему, позволяющий установить, что вы аутентифицированы. Поэтому мой подход заключается в том, чтобы сначала опубликовать сообщение на странице входа в систему, принять cookie для проверки подлинности с помощью форм, а затем продолжить выполнять любые последующие запросы, которые вы хотите сделать. Все последующие запросы уже содержат файл cookie для проверки подлинности форм.

1 голос
/ 06 января 2012

Во время сеансовой аутентификации (то, что вы называете «аутентификацией на основе форм»), Domino генерирует так называемый LTPA-токен (cookie) для дальнейшей аутентификации пользователя.

Самый простой способ получить это - эмулировать браузер / пользователя, отправив на сервер форму входа с необходимыми данными формы, извлечь файл cookie LTPA из ответа сервера и использовать его в дальнейших запросах. Вы можете использовать, например, WatiN , чтобы упростить это.

Или вы можете рассчитать стоимость куки, прежде чем генерировать его самостоятельно. Формат ... файла cookie LTPA легко найти через Google, но это не тривиально, и вам нужны некоторые данные с сервера.

Если вы делаете это с сервером, с которым вы знакомы с администратором, вы можете попросить его добавить правило веб-сайта, которое позволяет использовать базовую аутентификацию для подмножества запросов, в то время как на основе сеанса аутентификация используется для остальной части веб-сайта.

...