문제

저는 사용자가 파일을 업로드할 수 있도록 ASP.Net 웹 사이트에서 Yahoo UI 라이브러리의 일부인 Yahoo Uploader를 사용하고 있습니다.익숙하지 않은 분들을 위해 설명하자면, 업로더는 Flash 애플릿을 사용하여 FileOpen 대화 상자에 대한 더 많은 제어권을 제공합니다.파일 형식에 대한 필터를 지정하고 여러 파일을 선택할 수 있도록 허용하는 등의 작업을 수행할 수 있습니다.훌륭하지만 다음과 같은 문서화된 제한 사항이 있습니다.

알려진 플래시 버그로 인해 Windows의 Firefox에서 실행되는 업로더는 업로드 시 올바른 쿠키를 보내지 않습니다.Firefox 쿠키를 보내는 대신 해당 도메인에 대한 Internet Explorer의 쿠키를 보냅니다.이 문제를 해결하려면 쿠키를 사용하지 않는 업로드 방법을 사용하거나 업로드 요청에 document.cookie를 추가하는 것이 좋습니다.

따라서 사용자가 Firefox를 사용하는 경우 파일을 업로드할 때 쿠키를 사용하여 세션을 유지할 수 없습니다.나는 그들이 누구인지 알아야 하기 때문에 그들의 세션이 필요합니다!해결 방법으로 다음과 같이 Application 개체를 사용하고 있습니다.

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

그래서 저는 고유한 ID를 생성하고 이를 저장하는 키로 사용하고 있습니다. Page.User 응용 프로그램 범위의 개체입니다.파일이 업로드될 때 POST에 해당 ID를 변수로 포함합니다.그런 다음 파일 업로드를 허용하는 핸들러에서 다음과 같이 User 개체를 가져옵니다.

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

이는 실제로 작동하지만 두 가지 눈에 띄는 단점이 있습니다.

  • 사용자가 업로드 페이지를 방문하고 실제로 파일을 업로드하는 사이에 IIS, 앱 풀 또는 애플리케이션만 다시 시작되면 해당 "uploadid"가 애플리케이션 범위에서 삭제되고 인증할 수 없기 때문에 업로드가 실패합니다. .

  • 웹 팜(아마도 웹 가든) 시나리오로 확장하면 이는 완전히 중단됩니다.앞으로 이 앱을 확장할 계획을 제외하고는 걱정하지 않을 수도 있습니다.

누구든지 더 좋은 방법이 있습니까?POST 변수에 실제 ASP.Net 세션 ID를 전달한 다음 반대쪽 끝에서 해당 ID를 사용하여 세션을 검색할 수 있는 방법이 있습니까?

세션 ID를 얻을 수 있다는 것을 알고 있습니다. Session.SessionID, 그리고 YUI를 사용하여 다음 페이지에 게시하는 방법을 알고 있습니다.내가 모르는 것은 그것을 어떻게 사용하는가이다. SessionID 상태 서버에서 세션을 가져옵니다.

예, 상태 서버를 사용하여 세션을 저장하고 있으므로 세션은 응용 프로그램/IIS 다시 시작을 유지하고 웹 팜 시나리오에서 작동합니다.

도움이 되었습니까?

해결책

여기 관리자의 게시물입니다. SWF업로드 Request.Form에 저장된 ID에서 세션을 로드하는 방법을 설명합니다.Yahoo 구성 요소에서도 동일한 작업이 수행될 것이라고 생각합니다.

게시물 하단의 보안 면책 조항을 참고하세요.


Global.asax 파일과 다음 코드를 포함하면 누락된 세션 ID 쿠키를 재정의할 수 있습니다.

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 응용 프로그램에 이 코드를 복사하여 붙여넣지 마십시오.Cross-site Scripting의 보안 문제와 가능성을 소개합니다.

다른 팁

다음 코드에서 현재 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 숨겨진 필드에 설정한 후 다음 페이지에 게시할 수 있습니다.

그러나 응용 프로그램을 다시 시작하지 않으면 sessionID가 만료될 것이라고 생각합니다. SQL Server에 세션 저장.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top