Share via


Implementar un proveedor de almacén de estados de sesión

Actualización: noviembre 2007

Describe la implementación de un proveedor de almacenes de estados de sesión personalizado y muestra cómo se implementa un proveedor de ejemplo.

El estado de sesión de ASP.NET está diseñado para permitir almacenar datos de la sesión de usuario en orígenes diferentes. De forma predeterminada, los valores y la información del estado de sesión se almacenan en memoria en el proceso de ASP.NET. Si lo desea, también puede almacenar los datos de la sesión en un servidor de estado, que mantendrá los datos de la sesión en un proceso diferente y los conservará si se cierra o se reinicia la aplicación ASP.NET. Otra alternativa es almacenar los datos de la sesión en una base de datos de SQL Server, donde varios servidores Web pueden compartir esta información.

Puede utilizar los almacenes de estados de sesión incluidos con ASP.NET o puede implementar su propio proveedor de almacén de estados de sesión. Puede crear un proveedor de almacén de estados de sesión personalizado por los motivos siguientes:

  • Necesita almacenar la información del estado de sesión en un origen de datos distinto de SQL Server, como una base de datos de FoxPro o una base de datos de Oracle.

  • Necesita administrar la información de estado de sesión mediante un esquema de base de datos diferente del que utilizan los proveedores que se distribuyen con .NET Framework. Un ejemplo de esta situación son los datos del carro de la compra que se almacenan con un esquema predefinido en la base de datos de SQL Server existente.

Puede implementar un proveedor de almacenes de estados de sesión personalizado creando una clase que herede la clase SessionStateStoreProviderBase. Para obtener más información, consulte la sección "Clases requeridas", más adelante en este mismo tema.

Módulo de estado de sesión

El estado de la sesión se administra mediante la clase SessionStateModule, que llama al proveedor del almacén de estados de sesión para que lea y escriba los datos de la sesión en el almacén de datos en momentos diferentes durante una solicitud. Al comienzo de una solicitud, la instancia de SessionStateModule recupera los datos del origen de datos llamando al método GetItemExclusive, o si el atributo de página EnableSessionState se ha establecido en ReadOnly, llamando al método GetItem. Al final de una solicitud, si se han modificado los valores del estado de sesión, la instancia de SessionStateModule llama al método SessionStateStoreProviderBase.SetAndReleaseItemExclusive para escribir los valores actualizados en el almacén de estados de sesión. SessionStateModule llama a los miembros adicionales de la implementación SessionStateStoreProviderBase para inicializar una nueva sesión y para eliminar los datos de la sesión del almacén de datos cuando se llama al método HttpSessionState.Abandon. Cada miembro de la clase SessionStateStoreProviderBase se explica de forma más detallada en la sección "Clases requeridas", más adelante en este mismo tema.

La clase SessionStateModule determina el propio valor SessionID, en lugar de basarse en el proveedor de almacén de estados de sesión. Si es necesario, puede implementar una clase SessionIDManager personalizada creando una clase que herede la interfaz ISessionIDManager. Para obtener más información, consulte la sección "Comentarios" en ISessionIDManager.

SessionStateModule recuperará la identidad de proceso de ASP.NET para obtener acceso a los recursos protegidos, como un servidor de bases de datos. Puede especificar que la instancia de SessionStateModule suplante la identidad proporcionada por IIS estableciendo el atributo useHostingIdentity del elemento de configuración <sessionState> en false. Por ejemplo, si ha configurado su aplicación de IIS para que utilice la seguridad integrada de Windows y desea que ASP.NET suplante la identidad proporcionada por IIS para la administración de sesiones, especifique <identity impersonate="true" /> en la sección de configuración <system.web> del archivo Web.config de la aplicación y establezca el atributo useHostingIdentity del elemento de configuración <sessionState> en false. Si el atributo useHostingIdentity es true, ASP.NET suplantará la identidad del proceso o las credenciales del usuario proporcionadas en el elemento de configuración <identity> (si existen), al conectarse al origen de datos. Para obtener más información sobre la identidad de procesos en ASP.NET, vea Configurar la identidad de procesos en ASP.NET y Suplantación de ASP.NET.

Bloquear datos del almacén de sesiones

Las aplicaciones ASP.NET son multiproceso y, por tanto, pueden responder a varias solicitudes simultáneas. Varias solicitudes simultáneas pueden intentar tener acceso a la misma información de sesión. Imagine una situación en la que varios marcos de un conjunto de marcos hacen referencia a páginas Web ASP.NET de la misma aplicación. Las diferentes solicitudes de cada marco se pueden ejecutar simultáneamente en el servidor Web en subprocesos diferentes. Si las páginas ASP.NET de cada marco tienen acceso a las variables de estado de sesión, podría tener varios subprocesos que obtuvieran acceso al almacén de sesiones simultáneamente. Para evitar colisiones de los datos en el almacén de sesiones y un comportamiento inesperado del estado de sesión, las clases SessionStateModule y SessionStateStoreProviderBase incluyen una funcionalidad que bloquea exclusivamente el elemento del almacén de sesiones de una sesión en particular durante la ejecución de una página ASP.NET. Tenga en cuenta que no se establece bloqueo alguno en un elemento del almacén de sesiones si el atributo EnableSessionState está marcado como ReadOnly. Sin embargo, es posible que otras páginas ASP.NET de la misma aplicación puedan escribir en el almacén de sesión; por tanto, una solicitud de los datos de sesión de sólo lectura del almacén podría tener que esperar a que se liberen los datos bloqueados.

Se establece un bloqueo en los datos del almacén de sesiones al comienzo de la solicitud durante la llamada al método GetItemExclusive. Cuando la solicitud finaliza, se libera el bloqueo durante la llamada al método SetAndReleaseItemExclusive.

Si la instancia de SessionStateModule encuentra datos de sesión bloqueados durante la llamada al método GetItemExclusive o GetItem, volverá a solicitar los datos de la sesión en intervalos de medio segundo hasta que el bloqueo se libere o se agote la cantidad de tiempo especificada en la propiedad ExecutionTimeout. Si la solicitud expira, SessionStateModule llama al método ReleaseItemExclusive para que libere los datos del almacén de sesión y los solicite en ese momento.

Los datos bloqueados del almacén de sesiones se pueden liberar con una llamada al método ReleaseItemExclusive en un subproceso diferente, antes de realizar la llamada al método SetAndReleaseItemExclusive de la respuesta actual. Esto podría ocasionar que la instancia de SessionStateModule estableciera y liberara datos del almacén de estados de sesión que ya se han liberado y modificado en otra sesión. Para evitar esta situación, SessionStateModule incluye un identificador de bloqueo con cada solicitud para modificar los datos bloqueados del almacén de sesiones. Los datos del almacén de sesiones sólo se modifican si el identificador de bloqueo del almacén de datos coincide con el identificador de bloqueo proporcionado por SessionStateModule.

Eliminar datos expirados del almacén de sesiones

Cuando se llama al método Abandon para una sesión, los datos de esa sesión se eliminan del almacén de datos mediante el método RemoveItem. De lo contrario, los datos permanecen en el almacén de datos de la sesión para atender solicitudes futuras durante la sesión.

El mecanismo para eliminar los datos de sesión expirados depende de las funciones del origen de datos. Si el origen de datos se puede configurar para que elimine los datos de sesión expirados en función de la propiedad Timeout de la sesión, puede utilizar el método SetItemExpireCallback para hacer referencia al delegado del evento Session_OnEnd y provocarlo cuando se eliminen los datos de sesión expirados.

ApplicationName

Para mantener el ámbito de la sesión, los proveedores de estados de sesión guardan por separado la información de sesión de cada aplicación. De esta forma, varias aplicaciones ASP.NET pueden usar el mismo origen de datos sin entrar en conflicto en caso de que se encuentren identificadores de sesión duplicados.

Dado que los proveedores de almacén de estados de sesión guardan por separado la información de sesión de cada aplicación, deberá asegurarse de que el esquema de datos, las consultas y las actualizaciones incluyen el nombre de la aplicación. Por ejemplo, se podría utilizar el comando siguiente para recuperar los datos de sesión de una base de datos.

SELECT * FROM Sessions 
  WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication'

Si lo desea, puede almacenar también una combinación del identificador de sesión y el nombre de la aplicación como un identificador exclusivo de un elemento del almacén de datos de estados de sesión.

Clases requeridas

Para implementar un proveedor de almacenes de estados de sesión, cree una clase que herede la clase abstracta SessionStateStoreProviderBase. La clase SessionStateStoreProviderBase hereda a su vez la clase abstracta ProviderBase, por lo que también debe implementar los miembros necesarios de la clase ProviderBase. En las tablas siguientes se muestran las propiedades y los métodos que debe implementar a partir de las clases abstractas ProviderBase y SessionStateStoreProviderBase, y se proporciona una descripción de cada uno de ellos. Para consultar una implementación de cada miembro, vea Proveedor de almacén de estados de sesión de ejemplo.

Miembros de ProviderBase necesarios

Member

Descripción

Initialize (método)

Toma como entrada el nombre del proveedor y un instancia de NameValueCollection de valores de configuración. Este método se utiliza para establecer los valores de las propiedades en la instancia del proveedor, entre los que se incluyen los valores específicos de la implementación y las opciones especificadas en el archivo de configuración (Machine.config o Web.config).

Miembros de SessionStateStoreProvider necesarios

Member

Descripción

Método InitializeRequest

Toma como entrada la instancia de HttpContext de la solicitud actual y realiza cualquier inicialización requerida por el proveedor de almacén de estados de sesión.

Método EndRequest

Toma como entrada la instancia de HttpContext de la solicitud actual y realiza cualquier limpieza requerida por el proveedor de almacén de estados de sesión.

Método Dispose

Libera todos los recursos que el proveedor de almacenes de estados de sesión no está utilizando.

Método GetItemExclusive

Toma como entrada la instancia de HttpContext de la solicitud actual y el valor SessionID de la solicitud actual. Recupera la información y los valores de la sesión del almacén de datos de sesión y bloquea los datos de los elementos de la sesión en el almacén de datos durante la solicitud. El método GetItemExclusive establece varios valores de parámetros de salida que informan al control SessionStateModule que realiza la llamada sobre el estado del elemento del estado de sesión actual del almacén de datos.

Si no se encuentra ningún dato de elementos de sesión en el almacén de datos, el método GetItemExclusive establece el parámetro de salida locked en false y devuelve null. Esto hará que SessionStateModule llame al método CreateNewStoreData para crear un nuevo objeto SessionStateStoreData para la solicitud.

Si se encuentran datos de elementos de sesión en el almacén de datos pero están bloqueados, el método GetItemExclusive establece el parámetro de salida locked en true, establece el parámetro de salida lockAge en una fecha y hora que se obtiene al restar la fecha y la hora en que se bloqueó el elemento de la fecha y hora actuales, establece el parámetro de salida lockId en el identificador de bloqueo recuperado del almacén de datos y devuelve null. Esto hace que SessionStateModule llame de nuevo al método GetItemExclusive después de un intervalo de medio segundo, intente recuperar la información del elemento de sesión y obtenga un bloqueo de los datos. Si el valor en el que se establece el parámetro de salida lockAge supera el valor ExecutionTimeout, SessionStateModule llama al método ReleaseItemExclusive para liberar el bloqueo de los datos de los elementos de la sesión y, a continuación, vuelve a llamar al método GetItemExclusive.

El parámetro actionFlags se utiliza con sesiones cuya propiedad Cookieless es true, cuando el atributo regenerateExpiredSessionId está establecido en true. Un valor actionFlags establecido en InitializeItem (1) indica que la entrada del almacén de datos de sesión es una nueva sesión que requiere inicialización. Las entradas no inicializadas en el almacén de datos de sesión se crean mediante una llamada al método CreateUninitializedItem. Si ya se ha inicializado el elemento del almacén de datos de sesión, el parámetro actionFlags se establece en cero.

Si su proveedor admite sesiones sin cookies, establezca al parámetro de salida actionFlags en el valor devuelto por el almacén de datos de sesión del elemento actual. Si el valor del parámetro actionFlags del elemento del almacén de sesiones solicitado es igual al valor de enumeración InitializeItem (1), el método GetItemExclusive debe establecer el valor del almacén de datos en cero después de definir el parámetro actionFlagsout.

Método GetItem

Este método realiza la misma función que el método GetItemExclusive, con la salvedad de que no intenta bloquear el elemento de sesión del almacén de datos. Se llama al método GetItem cuando el atributo EnableSessionState se establece en ReadOnly.

Método SetAndReleaseItemExclusive

Toma como entrada la instancia de HttpContext de la solicitud actual, el valor SessionID de la solicitud actual, un objeto SessionStateStoreData que contiene los valores de la sesión actual que se van a almacenar, el identificador de bloqueo de la solicitud actual y un valor que indica si los datos que se van a almacenar están destinados a una nueva sesión o a una sesión existente.

Si el parámetro newItem es true, el método SetAndReleaseItemExclusive inserta un nuevo elemento en el almacén de datos con los valores proporcionados. De lo contrario, el elemento existente en el almacén de datos se actualiza con los valores proporcionados y se libera el bloqueo de los datos. Tenga en cuenta que sólo se actualizan los datos de sesión de la aplicación actual que coinciden con el valor SessionID proporcionado y con los valores del identificador de bloqueo.

Después de llamar al método SetAndReleaseItemExclusive, SessionStateModule llama al método ResetItemTimeout para actualizar la fecha y la hora de expiración de los datos de los elementos de la sesión.

Método ReleaseItemExclusive

Toma como entrada la instancia de HttpContext de la solicitud actual, el valor SessionID de la solicitud actual y el identificador de bloqueo de la solicitud actual, y libera el bloqueo de un elemento situado en el almacén de datos de sesión. La llamada a este método se produce cuando se llama al método GetItem o GetItemExclusive y el almacén de datos establece que se bloquee el elemento solicitado, pero el tiempo de bloqueo supera el valor ExecutionTimeout. Este método elimina el bloqueo, y libera al elemento para que pueda utilizarse en otras solicitudes.

Método RemoveItem

Toma como entrada la instancia de HttpContext de la solicitud actual, el valor SessionID de la solicitud actual y el identificador de bloqueo de la solicitud actual, y elimina la información de sesión del almacén de datos en la que el elemento del almacén de datos coincide con el valor SessionID proporcionado, la aplicación actual y el identificador de bloqueo proporcionado. La llamada a este método se realiza cuando se llama al método Abandon.

Método CreateUninitializedItem

Toma como entrada la instancia de HttpContext de la solicitud actual, el valor SessionID de la solicitud actual y el identificador de bloqueo de la solicitud actual, y agrega un elemento no inicializado al almacén de datos de sesión con un valor actionFlags de InitializeItem.

El método CreateUninitializedItem se utiliza con sesiones sin cookies cuando el atributo regenerateExpiredSessionId está establecido en true, lo que hace que SessionStateModule genere un nuevo valor SessionID cuando se encuentra un Id. de sesión expirado.

El proceso de generación de un nuevo valor SessionID exige redirigir el explorador a una dirección URL que contenga el Id. de sesión recién generado. El método CreateUninitializedItem se llama durante una solicitud inicial que contiene un Id. de sesión expirado. Después de que SessionStateModule adquiere un nuevo valor SessionID para reemplazar el Id. de sesión expirado, llama al método CreateUninitializedItem para agregar una entrada no inicializada al almacén de datos de estados de sesión. El explorador se desplaza a continuación a la dirección URL que contiene el valor SessionID que se acaba de generar. La existencia de la entrada no inicializada en el almacén de datos de la sesión garantiza que la solicitud redirigida con el valor SessionID recién generado no se confunda con una solicitud de una sesión expirada y, en su lugar, se trate como una nueva sesión.

La entrada no inicializada del almacén de datos de sesión está asociada con el valor SessionID recién generado y sólo contiene valores predeterminados, incluidas la fecha y la hora de expiración y un valor que se corresponde con el parámetro actionFlags de los métodos GetItem y GetItemExclusive. La entrada no inicializada del almacén de estados de sesión debe incluir un valor actionFlags que sea igual al valor de enumeración InitializeItem (1). Este valor se pasa a SessionStateModule mediante los métodos GetItem y GetItemExclusive, y especifica para SessionStateModule que la sesión actual es una nueva sesión. SessionStateModule inicializará a continuación la nueva sesión y provocará el evento Session_OnStart.

Método CreateNewStoreData

Toma como entrada la instancia de HttpContext de la solicitud actual y el valor Timeout de la sesión actual, y devuelve un nuevo objeto SessionStateStoreData con un objeto ISessionStateItemCollection vacío, una colección HttpStaticObjectsCollection y el valor Timeout especificado. La instancia de HttpStaticObjectsCollection de la aplicación ASP.NET se puede recuperar utilizando el método GetSessionStaticObjects.

Método SetItemExpireCallback

Toma como entrada un delegado que hace referencia al evento Session_OnEnd definido en el archivo Global.asax. Si el proveedor del almacén de estados de sesión admite el evento Session_OnEnd, se establece una referencia local al parámetro SessionStateItemExpireCallback y el método devuelve true; en caso contrario, el método devuelve false.

Proveedor de ejemplo

Para ver una implementación de ejemplo de un proveedor de almacén de estados de sesión personalizado que administra información de la sesión en una base de datos de Access, consulte Proveedor de almacén de estados de sesión de ejemplo.

Vea también

Conceptos

Proveedor de almacén de estados de sesión de ejemplo

Información general sobre el estado de sesión de ASP.NET

Información general sobre la administración de estados de ASP.NET