ASP.Net セッション ID を非表示のフォーム フィールドに入力できますか?

StackOverflow https://stackoverflow.com/questions/43324

  •  09-06-2019
  •  | 
  •  

質問

私は、ユーザーがファイルをアップロードできるように、ASP.Net Web サイトで Yahoo UI ライブラリの一部である Yahoo アップローダーを使用しています。よく知らない人のために説明すると、アップローダーは Flash アプレットを使用して機能し、[ファイルを開く] ダイアログをより詳細に制御できるようになります。ファイルタイプのフィルターを指定したり、複数のファイルを選択できるようにしたりできます。それは素晴らしいことですが、次のような制限事項が文書化されています。

既知の Flash バグのため、Windows の Firefox で実行されているアップローダーは、アップロード時に正しい Cookie を送信しません。Firefox の Cookie を送信する代わりに、それぞれのドメインの Internet Explorer の Cookie を送信します。回避策として、Cookie を使用しないアップロード方法を使用するか、アップロード リクエストに document.cookie を追加することをお勧めします。

したがって、ユーザーが Firefox を使用している場合、ファイルをアップロードするときにセッションを維持するために Cookie を信頼することはできません。彼らが誰なのか知りたいので、彼らのセッションが必要です。回避策として、私は Application オブジェクトを次のように使用しています。

Guid UploadID = Guid.NewGuid();
Application.Add(Guid.ToString(), User);

そこで、一意の ID を作成し、それをキーとして使用して、 Page.User Application スコープ内のオブジェクト。ファイルがアップロードされるときに、その ID を変数として POST に含めます。次に、ファイルのアップロードを受け入れるハンドラーで、次のように User オブジェクトを取得します。

IPrincipal User = (IPrincipal)Application[Request.Form["uploadid"]];

これは実際には機能しますが、明らかな欠点が 2 つあります。

  • ユーザーがアップロード ページにアクセスしてから実際にファイルをアップロードするまでの間に、IIS、アプリ プール、またはアプリケーションだけが再起動されると、その「uploadid」がアプリケーション スコープから削除され、認証できないためアップロードが失敗します。 。

  • Web ファーム (おそらく Web ガーデン) のシナリオに拡張すると、これは完全に壊れてしまいます。将来的にこのアプリを拡張する予定があることを除けば、心配する必要はないかもしれません。

もっと良い方法がある人はいますか?実際の ASP.Net セッション ID を POST 変数に渡し、その ID を相手側で使用してセッションを取得する方法はありますか?

セッションIDを取得できることはわかっています Session.SessionID, そして、YUI を使用して次のページに投稿する方法を知っています。わからないのはそれをどう使うかです SessionID 状態サーバーからセッションを取得します。

はい、状態サーバーを使用してセッションを保存しているため、セッションはアプリケーション/IIS の再起動後も保持され、Web ファーム シナリオで動作します。

役に立ちましたか?

解決

ここ のメンテナーからの投稿です SWFアップロード ここでは、Request.Form に保存されている ID からセッションをロードする方法について説明します。同じことが Yahoo コンポーネントでも機能すると思います。

投稿の下部にあるセキュリティ上の免責事項に注意してください。


Global.asax ファイルと次のコードを含めることで、不足しているセッション ID Cookie をオーバーライドできます。

using System;
using System.Web;

public class Global_asax : System.Web.HttpApplication
{
    private void Application_BeginRequest(object sender, EventArgs e)
    {
        /* 
        Fix for the Flash Player Cookie bug in Non-IE browsers.
        Since Flash Player always sends the IE cookies even in FireFox
        we have to bypass the cookies by sending the values as part of the POST or GET
        and overwrite the cookies with the passed in values.

        The theory is that at this point (BeginRequest) the cookies have not been ready by
        the Session and Authentication logic and if we update the cookies here we'll get our
        Session and Authentication restored correctly
        */

        HttpRequest request = HttpContext.Current.Request;

        try
        {
            string sessionParamName = "ASPSESSID";
            string sessionCookieName = "ASP.NET_SESSIONID";

            string sessionValue = request.Form[sessionParamName] ?? request.QueryString[sessionParamName];
            if (sessionValue != null)
            {
                UpdateCookie(sessionCookieName, sessionValue);
            }
        }
        catch (Exception ex)
        {
            // TODO: Add logging here.
        }

        try
        {
            string authParamName = "AUTHID";
            string authCookieName = FormsAuthentication.FormsCookieName;

            string authValue = request.Form[authParamName] ?? request.QueryString[authParamName];
            if (authValue != null)
            {
                UpdateCookie(authCookieName, authValue);
            }
        }
        catch (Exception ex)
        {
            // TODO: Add logging here.
        }
    }

    private void UpdateCookie(string cookieName, string cookieValue)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookieName);
        if (cookie == null)
        {
            HttpCookie newCookie = new HttpCookie(cookieName, cookieValue);
            Response.Cookies.Add(newCookie);
        }
        else
        {
            cookie.Value = cookieValue;
            HttpContext.Current.Request.Cookies.Set(cookie);
        }
    }
}

セキュリティ警告: 何をしているのかも知らずに、単にこのコードをコピーして ASP.Net アプリケーションに貼り付けないでください。セキュリティの問題とクロスサイト スクリプティングの可能性について紹介します。

他のヒント

次のコードから現在の SessionID を取得できます。

string sessionId = HttpContext.Current.Session.SessionID;

次に、それを隠しフィールドにフィードし、YUI を通じてその値にアクセスできます。

これは単なる取得なので、スケーリングの問題が発生しないことを願っています。ただし、セキュリティの問題はわかりません。

頼りにしている このブログ投稿, 、セッション ID に基づいて任意のユーザーのセッションを取得する関数を次に示します。ただし、見た目は良くありません。

public SessionStateStoreData GetSessionById(string sessionId)
{
    HttpApplication httpApplication = HttpContext.ApplicationInstance;

    // Black magic #1: getting to SessionStateModule
    HttpModuleCollection httpModuleCollection = httpApplication.Modules;
    SessionStateModule sessionHttpModule = httpModuleCollection["Session"] as SessionStateModule;
    if (sessionHttpModule == null)
    {
        // Couldn't find Session module
        return null;
    }

    // Black magic #2: getting to SessionStateStoreProviderBase through reflection
    FieldInfo fieldInfo = typeof(SessionStateModule).GetField("_store", BindingFlags.NonPublic | BindingFlags.Instance);
    SessionStateStoreProviderBase sessionStateStoreProviderBase = fieldInfo.GetValue(sessionHttpModule) as SessionStateStoreProviderBase;
    if (sessionStateStoreProviderBase == null)
    {
        // Couldn't find sessionStateStoreProviderBase
        return null;
    }

    // Black magic #3: generating dummy HttpContext out of the thin air. sessionStateStoreProviderBase.GetItem in #4 needs it.
    SimpleWorkerRequest request = new SimpleWorkerRequest("dummy.html", null, new StringWriter());
    HttpContext context = new HttpContext(request);

    // Black magic #4: using sessionStateStoreProviderBase.GetItem to fetch the data from session with given Id.
    bool locked;
    TimeSpan lockAge;
    object lockId;
    SessionStateActions actions;
    SessionStateStoreData sessionStateStoreData = sessionStateStoreProviderBase.GetItem(
        context, sessionId, out locked, out lockAge, out lockId, out actions);
    return sessionStateStoreData;
}

ASP.Net セッション ID は次の場所に保存されます。 Session.SessionID したがって、それを非表示フィールドに設定して、次のページに投稿できます。

ただし、アプリケーションが再起動すると、セッションIDは期限切れになると思います。 セッションをSQLサーバーに保存します.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top