2008-09-04 23 views
9

Tôi đang sử dụng Trình tải lên của Yahoo, một phần của Thư viện giao diện người dùng Yahoo, trên trang web ASP.Net của tôi để cho phép người dùng tải tệp lên. Đối với những người không quen thuộc, người tải lên hoạt động bằng cách sử dụng một applet Flash để cho tôi quyền kiểm soát nhiều hơn đối với hộp thoại FileOpen. Tôi có thể chỉ định bộ lọc cho các loại tệp, cho phép nhiều tệp được chọn, v.v. Rất tuyệt, nhưng có giới hạn được ghi lại sau đây:Tôi có thể đặt ID phiên ASP.Net trong trường biểu mẫu ẩn không?

Do lỗi Flash đã biết, Trình tải lên đang chạy trong Firefox trong Windows không gửi đúng cookie với nội dung tải lên; thay vì gửi cookie của Firefox, nó sẽ gửi cookie của Internet Explorer cho miền tương ứng. Để giải quyết vấn đề này, chúng tôi khuyên bạn nên sử dụng phương pháp tải lên không có cookie hoặc thêm document.cookie vào yêu cầu tải lên.

Vì vậy, nếu người dùng đang sử dụng Firefox, tôi không thể dựa vào cookie để duy trì phiên của họ khi họ tải tệp lên. Tôi cần phiên của họ vì tôi cần biết họ là ai! Là một workaround, tôi đang sử dụng đối tượng Application thusly:

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

Vì vậy, tôi đang tạo ra một ID duy nhất và sử dụng nó như một chìa khóa để lưu trữ các đối tượng Page.User trong phạm vi ứng dụng. Tôi đưa ID đó làm biến trong POST khi tệp được tải lên. Sau đó, trong xử lý chấp nhận các tập tin tải lên, tôi lấy đối tượng người dùng thusly:

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

thực này hoạt động, nhưng nó có hai nhược điểm rõ ràng:

  • Nếu IIS, hồ bơi ứng dụng, hoặc thậm chí chỉ ứng dụng được khởi động lại giữa thời gian người dùng truy cập trang tải lên và thực sự tải lên tệp, "nội dung tải lên" của họ bị xóa khỏi phạm vi ứng dụng và tải lên không thành công vì tôi không thể xác thực chúng.

  • Nếu tôi từng chia tỷ lệ thành một trang trại trên web (có thể là một khu vườn trên web), điều này sẽ hoàn toàn phá vỡ. Tôi có thể không lo lắng, ngoại trừ tôi có kế hoạch mở rộng ứng dụng này trong tương lai.

Có ai có cách nào tốt hơn không? Có cách nào để tôi vượt qua ID phiên ASP.Net thực tế trong một biến POST, sau đó sử dụng ID đó ở đầu kia để lấy phiên?

Tôi biết tôi có thể lấy ID phiên qua Session.SessionID và tôi biết cách sử dụng YUI để đăng nó lên trang tiếp theo. Những gì tôi không biết là làm thế nào để sử dụng SessionID để lấy phiên từ máy chủ trạng thái.

Có, tôi đang sử dụng máy chủ trạng thái để lưu trữ các phiên, do đó chúng vẫn tiếp tục chạy ứng dụng/IIS và sẽ hoạt động trong một kịch bản trang trại.

Trả lời

3

Here là bài đăng từ người duy trì SWFUpload giải thích cách tải phiên từ ID được lưu trữ trong Request.Form. Tôi tưởng tượng điều tương tự sẽ làm việc cho thành phần của Yahoo.

Lưu ý tuyên bố từ chối trách nhiệm bảo mật ở cuối bài đăng.


Bằng cách đưa một file Global.asax và đoạn mã sau bạn có thể ghi đè lên các tập tin cookie Session ID mất tích:

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

An ninh Cảnh báo: Đừng chỉ cần sao chép và dán mã này vào ứng dụng ASP.Net của bạn mà không biết bạn đang làm gì. Nó giới thiệu các vấn đề bảo mật và khả năng của Cross-site Scripting.

+0

Đây chính là điều tôi đang tìm kiếm. Cảm ơn! –

+7

Hey ... liên kết dường như bị hỏng..có thể cập nhật u? – Mulki

+2

có, chúng tôi cần điều này! vui lòng cung cấp liên kết mới! – pilavdzice

0

ID phiên ASP.Net được lưu trữ trong Session.SessionID để bạn có thể đặt trong trường ẩn và sau đó đăng nó lên trang tiếp theo.

Tôi nghĩ, tuy nhiên, nếu ứng dụng khởi động lại, sessionID sẽ hết hạn nếu bạn không store your sessions in sql server.

1

Bạn có thể nhận SessionID hiện tại của bạn từ đoạn mã sau:

string sessionId = HttpContext.Current.Session.SessionID; 

Sau đó, bạn có thể thức ăn đó vào một lĩnh vực tiềm ẩn có thể và sau đó truy cập giá trị mà qua YUI.

Nó chỉ là một nhận được, vì vậy bạn hy vọng sẽ không có bất kỳ vấn đề mở rộng quy mô. Tuy nhiên, vấn đề an ninh, mà tôi không biết.

1

Dựa vào this blog post, đây là một chức năng mà nên giúp bạn có được phiên cho bất kỳ người sử dụng dựa trên ID phiên, mặc dù nó không đẹp:

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

Hoàn hảo! Cảm ơn bạn! – defines

Các vấn đề liên quan