10

ASP.NetWebサイトでYahooUIライブラリの一部であるYahooUploaderを使用して、ユーザーがファイルをアップロードできるようにしています。なじみのない人のために、アップローダーはFlashアプレットを使用して動作し、FileOpenダイアログをより細かく制御できるようにします。ファイルタイプのフィルターを指定したり、複数のファイルを選択したりすることができます。これはすばらしいことですが、次の文書化された制限があります。

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

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

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

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

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

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

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

  • Webファーム(場合によってはWebガーデン)のシナリオに拡張すると、これは完全に機能しなくなります。将来このアプリをスケーリングする予定がある場合を除いて、心配する必要はありません。

誰かがより良い方法を持っていますか?POST変数で実際のASP.NetセッションIDを渡し、もう一方の端でそのIDを使用してセッションを取得する方法はありますか?

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

はい、セッションを保存するために状態サーバーを使用しているので、それらはアプリケーション/ IISの再起動を永続化し、Webファームシナリオで機能します。

4

4 に答える 4

6

これは、Request.Form に保存された ID からセッションをロードする方法を説明するSWFUploadのメンテナーからの投稿です。同じことが 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 アプリケーションに貼り付けないでください。セキュリティの問題とクロスサイト スクリプティングの可能性を紹介します。

于 2008-10-26T07:12:50.483 に答える
2

このブログ投稿に依存して、セッション 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;
}
于 2014-09-10T00:49:30.287 に答える
1

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

string sessionId = HttpContext.Current.Session.SessionID;

次に、それを非表示フィールドにフィードして、YUIを介してその値にアクセスできます。

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

于 2008-09-04T08:42:45.140 に答える
0

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

ただし、アプリケーションを再起動した場合、セッションをSQL Serverに保存しないと、sessionIDが期限切れになると思います。

于 2008-09-04T08:41:17.937 に答える