web-dev-qa-db-ja.com

HttpCookieCollectionとCookieContainerを使用してCookieを送信する

サーバーからリモートサーバーへのHTTPリクエストをトンネリングし、すべてのCookieを通過させたい。そこで、新しいHttpWebRequestオブジェクトを作成し、それにCookieを設定したいと思います。

HttpWebRequest.CookieContainerはタイプSystem.Net.CookieContainerを保持しますSystem.Net.Cookies

着信リクエストオブジェクトについて:

HttpRequest.CookiesはタイプSystem.Web.HttpCookieCollectionを保持しますSystem.Web.HttpCookies

基本的にはお互いに割り当てたいのですが、タイプが違うので無理です。それらの値をコピーして変換する必要がありますか、それともより良い方法がありますか?

25
Mike

これが、受信リクエストから新しいHttpWebRequestにCookieオブジェクトを転送するために使用したコードです...(「myRequest」は私のHttpWebRequestオブジェクトの名前です)。

HttpCookieCollection oCookies = Request.Cookies;
for ( int j = 0; j < oCookies.Count; j++ ) 
{
    HttpCookie oCookie = oCookies.Get( j );
    Cookie oC = new Cookie();

    // Convert between the System.Net.Cookie to a System.Web.HttpCookie...
    oC.Domain   = myRequest.RequestUri.Host;
    oC.Expires  = oCookie.Expires;
    oC.Name     = oCookie.Name;
    oC.Path     = oCookie.Path;
    oC.Secure   = oCookie.Secure;
    oC.Value    = oCookie.Value;

    myRequest.CookieContainer.Add( oC );
}
36
David

今日、フォームベース認証(FBA)を使用するSharePointサイトでこれを行う必要がありました。 Cookieのクローンを作成してCookieContainerオブジェクトを割り当てずにアプリケーションページを呼び出そうとすると、リクエストは失敗します。

私はこの便利な拡張メソッドにジョブを抽象化することを選択しました。

public static CookieContainer GetCookieContainer(this System.Web.HttpRequest SourceHttpRequest, System.Net.HttpWebRequest TargetHttpWebRequest)
    {
        System.Web.HttpCookieCollection sourceCookies = SourceHttpRequest.Cookies;
        if (sourceCookies.Count == 0)
            return null;
        else
        {
            CookieContainer cookieContainer = new CookieContainer();
            for (int i = 0; i < sourceCookies.Count; i++)                
            {
                System.Web.HttpCookie cSource = sourceCookies[i];
                Cookie cookieTarget = new Cookie() { Domain = TargetHttpWebRequest.RequestUri.Host, 
                                                     Name = cSource.Name, 
                                                     Path = cSource.Path, 
                                                     Secure = cSource.Secure, 
                                                     Value = cSource.Value };
                cookieContainer.Add(cookieTarget);
            }
            return cookieContainer;
        }
    }

次に、ターゲットのHttpWebRequestオブジェクトをパラメーターとして使用して、任意のHttpRequestオブジェクトから呼び出すことができます。次に例を示します。

HttpWebRequest request;                
request = (HttpWebRequest)WebRequest.Create(TargetUrl);
request.Method = "GET";
request.Credentials = CredentialCache.DefaultCredentials;
request.CookieContainer = SourceRequest.GetCookieContainer(request);                
request.BeginGetResponse(null, null);

ここで、TargetUrlは私が探しているページのURLであり、SourceRequestはPage.Requestを介して取得された現在のページのHttpRequestです。

3
Colin Gardner

デビッドからの提案は正しいものです。コピーする必要があります。繰り返しコピーする関数を作成するだけです。 HttpCookieおよびCookieオブジェクトは、その機能とその場所の両方を区別できるようにするために作成されています。ユーザーとプロキシ間で使用されるHttpCookieCookieはプロキシとリモートWebサーバー間で使用されます。

Cookieはあなたから発信されたものであり、あなたはそれを処理する方法を知っているため、HttpCookieの機能は少なくなります。 Cookieは、Webサーバーから受信したCookieを管理するために提供されます。 CookieContainerと同様に、ドメイン、パス、有効期限の管理に使用できます。

そのため、ユーザー側とWebサーバー側は異なり、接続するには、必ず変換する必要があります。あなたの場合、それは単に直接の割り当てです。

CookieContainerの.Add(Cookie)メソッドと.GetCookies(uri)メソッドにバグがあることに注意してください。

詳細を参照して、ここで修正してください。

http://dot-net-expertise.blogspot.com/2009/10/cookiecontainer-domain-handling-bug-fix.html

CallMeLaNN

1
CallMeLaNN