簡體   English   中英

.NET - 使用基於表單的身份驗證在(Domino)服務器上使用HTTP服務

[英].NET - Consuming HTTP services on (Domino) server with form based authentication

我在C#(.NET)中編寫一個實用程序,它將使用HTTP從Domino Web服務器請求數據。

但是,此服務器使用基於表單的身份驗證,而不是基本HTTP身份驗

我試圖找到如何使用具有基於表單的身份驗證的服務器進行HTTP GETS / POSTS的代碼編寫。

我已經嘗試了我能想到的每個谷歌查詢,但只要在查詢中使用“基於表單的身份驗證”這些詞語,所有結果只適用於實現服務服務器端,通常在ASP.NET或Sharepoint中,關於從客戶端使用此類服務​​的結果。

我在Stack Overflow中看到了一個相關問題的Java代碼,但是用另一種語言在外國API中查找相關部分將是一次冒險。 如果有可用的.NET示例代碼或文檔,我將非常感激。

我相信有人可以提供更好的答案,但考慮到這一點,我會假設您托管Web服務的服務器具有某種登錄機制來確定您已經過身份驗證。 所以我的方法是首先發布到登錄頁面,接受表單身份驗證cookie,然后繼續處理您想要的任何后續請求。 以下所有請求中都已包含表單身份驗證cookie。

感謝所有提供提示的人。

我想分享我開發的代碼,以防它幫助其他人。 雖然它是專門為Domino服務器編寫的,但它應該很容易修改為任何基於cookie的身份驗證服務器的帖子中的實際字段名稱。

要使用該類:

  1. 創建DominoHttpSession,向其傳遞所有必需的屬性,例如服務器名稱,用戶名和密碼。
  2. 致電身份驗證
  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
                   };
        }

    }


}

在基於會話的身份驗證(您稱之為“基於表單的身份驗證”)期間,Domino會生成一個所謂的LTPA令牌 (cookie),以進一步驗證用戶身份。

最簡單的方法是通過將帶有必要表單數據的登錄表單發送到服務器來模擬瀏覽器/用戶,從服務器響應中提取LTPA cookie並在進一步的請求中使用它。 例如,您可以使用WatiN來簡化此操作。

或者你可以自己計算cookie的價值。 LTPA cookie的格式,...很容易通過谷歌找到,但它並不簡單,你需要服務器的一些數據。

如果您對服務器知道管理員這樣做,您可以要求他添加一個網站規則,允許對一部分請求使用基本身份驗證 ,而基於會話的身份驗證則用於其余的Web現場。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM