Pregunta

Yo estoy usando el de Yahoo Uploader, parte de la Biblioteca de interfaz de usuario de Yahoo, en mi ASP.Net sitio web para permitir a los usuarios subir archivos.Para aquellos no familiarizados con el cargador funciona mediante el uso de un Flash, applet que me dé más control sobre el diálogo FileOpen.Puedo especificar un filtro para los tipos de archivo, permitir que varios archivos seleccionados, etc.Es genial, pero tiene la siguiente información documentada limitación:

Debido a un conocido Flash error, el Uploader que se ejecuta en Firefox en Windows no enviar el correcto cookies con la carga;en lugar de enviar cookies de Firefox, envía las cookies de Internet Explorer para el dominio respectivo.Como solución, nos sugieren el uso de un sin método de carga o anexar documento.cookie para la solicitud de carga.

Por lo tanto, si un usuario está usando Firefox, yo no puedo confiar en cookies para conservar su sesión cuando se carga un archivo.Necesito su sesión porque necesito saber quienes son!Como solución, estoy usando el objeto de la Aplicación de este modo:

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

Por lo tanto, estoy creando un IDENTIFICADOR único y utilizando como clave para almacenar el Page.User objeto en el ámbito de la Aplicación.Tengo que incluir el ID como una variable en el POST cuando se carga el archivo.Luego, en el controlador que acepta la subida de los archivos, me agarra el objeto de Usuario de esta manera:

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

Esto realmente funciona, pero tiene dos evidentes inconvenientes:

  • Si IIS, la aplicación de la piscina, o simplemente se reinicia la aplicación entre el momento en que el usuario visita la página de carga, y en realidad se carga un archivo, su "uploadid" se elimina del ámbito de la aplicación y la carga se produce un error porque no puedo autenticar ellos.

  • Si alguna vez vuelvo a escala para una granja de servidores web (posiblemente incluso una web de jardín) escenario, este va a romper por completo.Yo podría no estar preocupado, excepto pienso sobre la ampliación de esta aplicación en el futuro.

¿Alguien tiene una mejor forma?Hay una manera para mí para pasar el real ASP.Net IDENTIFICADOR de sesión en una variable POST, a continuación, utilizar ese ID en el otro extremo para recuperar la sesión?

Sé que puedo obtener el IDENTIFICADOR de sesión a través de Session.SessionID, y yo sé cómo usar YUI para publicarlo en la página siguiente.Lo que no sé es cómo utilizar que SessionID para agarrar la sesión desde el servidor de estado.

Sí, estoy usando un servidor para almacenar las sesiones, por lo que persisten aplicación/IIS se reinicia y va a trabajar en una granja de servidores web escenario.

¿Fue útil?

Solución

Aquí es un post de el mantenedor de SWFUpload que explica cómo cargar la sesión de un IDENTIFICADOR almacenado en la Solicitud.El formulario.Me imagino que lo mismo funciona para Yahoo de componentes.

Nota: la seguridad de las renuncias en la parte inferior del post.


Mediante la inclusión de un Mundial.asax y el archivo de código siguiente se puede reemplazar la falta de la cookie de IDENTIFICACIÓN de Sesión:

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

Advertencia De Seguridad: No basta con copiar y pegar este código en tu ASP.Net aplicación sin saber lo que están haciendo.Se introduce a los problemas de seguridad y las posibilidades de Cross-site Scripting.

Otros consejos

Usted puede conseguir su actual SessionID desde el código siguiente:

string sessionId = HttpContext.Current.Session.SessionID;

A continuación, se puede alimentar a los que en un campo oculto tal vez y, a continuación, tener acceso a ese valor a través de YUI.

Es sólo un get, así que esperemos que no tienen problemas de escalado.Seguridad-a pesar de los problemas, que no lo sé.

Confiando en este blog, aquí una función que debe llegar a la reunión, para cualquier usuario basado en el IDENTIFICADOR de sesión, aunque no es bastante:

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

El ASP.Net IDENTIFICADOR de Sesión se almacena en Session.SessionID así se pudo establecer que en un campo oculto y, a continuación, publicarlo en la página siguiente.

Creo, sin embargo, que si la aplicación se reinicia, el sessionID caducará si no guarde sus sesiones en sql server.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top