2008-09-04 2 views
9

저는 사용자가 파일을 업로드 할 수 있도록하기 위해 ASP.Net 웹 사이트에서 Yahoo UI 라이브러리의 일부인 Yahoo 업 로더를 사용하고 있습니다. 익숙하지 않은 사용자를 위해 업 로더는 Flash 애플릿을 사용하여 FileOpen 대화 상자를보다 잘 제어 할 수 있습니다. 나는, 파일 형식에 대한 필터를 지정하는 여러 파일을 수 있도록 선택할 수 등이 큰, 그러나 다음과 같은 문서화 된 제한이 있습니다 :숨겨진 양식 필드에 ASP.Net 세션 ID를 넣을 수 있습니까?

이 때문에 알려진 플래시 버그의

, Windows에서 파이어 폭스에서 실행 업 로더가 수행을 업로드시 올바른 쿠키를 보내지 마십시오. Firefox 쿠키를 보내는 대신 해당 도메인에 대한 Internet Explorer의 쿠키를 보냅니다. 이 문제를 해결하려면 쿠키없는 업로드 방법을 사용하거나 document.cookie를 업로드 요청에 추가하는 것이 좋습니다.

그래서 사용자가 Firefox를 사용 중이라면 파일을 업로드 할 때 쿠키를 사용하여 세션을 유지할 수 없습니다. 나는 그들이 누구인지 알아야하기 때문에 그들의 세션이 필요하다! 이 문제를 해결 나는 thusly 히 Application 개체를 사용하고 있습니다 :

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

그래서, 나는 고유 ID를 생성하고 응용 프로그램 범위에서 Page.User 객체를 저장하는 키로 사용하고 있습니다. 파일을 업로드 할 때 해당 ID를 POST에 변수로 포함합니다. 이 실제로 작동

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

을하지만 두 눈부신 단점이 있습니다 : 그런 다음 파일 업로드를 허용하는 핸들러에서, 내가 thusly 히 사용자 개체를 잡아

  • IIS 경우, 응용 프로그램 풀, 심지어는 사용자가 업로드 페이지를 방문한 후 실제로 파일을 업로드 할 때까지 응용 프로그램이 다시 시작될 때 응용 프로그램 범위에서 해당 "uploadid"가 삭제되고 인증 할 수 없기 때문에 업로드가 실패합니다.

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

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

나는 Session.SessionID을 통해 세션 ID를 얻을 수 있다는 것을 알고 있으며 YUI를 사용하여 다음 페이지에 게시하는 방법을 알고 있습니다. 내가 모르는 것은 SessionID을 사용하여 상태 서버에서 세션을 가져 오는 방법입니다.

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

답변

3

Here은 Request.Form에 저장된 ID에서 세션을로드하는 방법을 설명하는 SWFUpload의 관리자입니다. 나는 야후 구성 요소에 대해 똑같은 일이 일어날 것이라고 상상한다.

게시물의 하단에 보안 고지 사항에 유의하십시오.

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); 
     } 
    } 
} 

보안 경고 :하십시오 Global.asax 파일을 포함하여 다음과 같은 코드가 누락 된 세션 ID 쿠키를 대체 할 수 있습니다함으로써


그냥 복사하지 마십시오 이 코드를 ASP.Net 응용 프로그램에 붙여 넣으십시오. 크로스 사이트 스크립팅의 보안 문제와 가능성을 소개합니다.

+0

이 내가 찾던 정확히 것입니다. 감사! –

+7

안녕하세요 ... 링크가 깨졌습니다 .. 업데이트 할 수 있습니까? – Mulki

+2

예, 우리는 이것을 필요로합니다! 새로운 링크를 제공해주세요! – pilavdzice

0

ASP.Net 세션 ID는 Session.SessionID에 저장되므로 숨겨진 필드에 설정 한 후 다음 페이지에 게시 할 수 있습니다.

그러나 응용 프로그램을 다시 시작하면 store your sessions in sql server을 입력하지 않으면 sessionID가 만료됩니다.

1

다음과 같은 코드에서 현재 세션 ID를 얻을 수 있습니다 :

string sessionId = HttpContext.Current.Session.SessionID; 

이 그럼 당신은 어쩌면 숨겨진 필드에 그 공급하고 YUI를 통해 그 값에 액세스 할 수 있습니다.

이것은 단지 얻는 것입니다. 따라서 아무런 스케일링 문제도 없기를 바랍니다. 보안 문제, 내가 모르는.

1

this blog post에 의존, 여기 꽤하지 비록 당신에게 세션 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; 
} 
+0

완벽! 고맙습니다! – defines

관련 문제