2009-10-12 11 views
10

Estoy trabajando en una aplicación que usa ASP.NET MVC 1.0 y estoy tratando de inyectar un objeto IPrincipal personalizado en el objeto HttpContext.Current.User.ASP.NET MVC inyección IPrincipal personalizada

Con una aplicación tradicional de WebForms he utilizado el evento Application_AuthenticateRequest para hacer esto de la siguiente manera.

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     if (HttpContext.Current.User != null) 
     { 
      if (HttpContext.Current.User.Identity.IsAuthenticated) 
      { 
       if (HttpContext.Current.User.Identity is FormsIdentity) 
       { 
        // Get Forms Identity From Current User 
        FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; 
        // Get Forms Ticket From Identity object 
        FormsAuthenticationTicket ticket = id.Ticket; 
        // Create a new Generic Principal Instance and assign to Current User 
        SiteUser siteUser = new SiteUser(Convert.ToInt32(id.Name)); 

        HttpContext.Current.User = siteUser; 
       } 
      } 
     } 

    } 

Así que el uso de este pude acceder a mi costumbre IPrincipal por cualquiera de fundición explícitamente el objeto de usuario para escribir SiteUser. De hecho, hice esto teniendo una clase personalizada que todas las páginas heredaban de la cual hice esto bajo las sábanas para mí.

De todos modos, mi problema es que con ASP.NET MVC la Application_AuthenticateRequest parece activarse cada vez que se realiza una solicitud (por ejemplo, para archivos JS, imágenes, etc.) que hace que la aplicación muera.

Cualquier ayuda o sugerencia sobre cómo puedo hacer para inyectar mi IPrincipal personalizado en el objeto HttpContext.Current.User dentro de ASP.NET MVC 1.0 sería muy apreciado. Vi la siguiente publicación en SO, pero no parecía atender a lo que estoy tratando de lograr: ASP.NET MVC - Set custom IIdentity or IPrincipal

TIA.

+0

Eso no debería morir, independientemente del tipo de archivo, ¿qué error estás viendo? – blowdart

+0

Recibo un "golpe" en el método Application_AuthenticateRequest para todos y cada uno de los recursos solicitados. Hace que las páginas rindan dolorosamente lentamente en comparación con las ejecuciones sin el método Application_AuthenticateRequest implementado. El constructor del objeto SiteUser no hace nada particularmente espectacular, solo obtiene los detalles del usuario y la lista de roles del DB. –

+0

Bueno, por supuesto que sí, así es como funciona IIS7 - Creí que se refería a morir con un error – blowdart

Respuesta

8

mi problema es que con ASP.NET MVC la Application_AuthenticateRequest parece disparar siempre que cualquier petición es hecha (por lo que para archivos JS, imágenes, etc.) que provoca la aplicación de morir.

Este no es un problema exclusivo de MVC: si ejecutó su aplicación en IIS7 con la interconexión integrada en su lugar, verá lo mismo.

Si el problema con las operaciones de búsqueda es la escalabilidad entonces asumen el problema real está dentro

FormsAuthenticationTicket ticket = id.Ticket; 
SiteUser siteUser = new SiteUser(Convert.ToInt32(id.Name)); 

supongo que su clase SiteUser hace algún tipo de consulta de base de datos. Si examina cómo funciona auth de formularios, el ticket contiene toda la información necesaria para generar un FormsIdentity (esto no es válido para los roles, a menos que habilite específicamente el almacenamiento en memoria caché de los roles de las cookies). Entonces deberías mirar el mismo enfoque. La primera vez que construya su objeto del sitio web, almacénelo en caché dentro de una cookie firmada, luego use la cookie para rehidratar sus propiedades de SiteUser en solicitudes posteriores.

Si hace esto, puede ir un paso más allá, reemplazando el principio del subproceso con su SiteUser, o al menos una combinación IPrincipal/IUser personalizada que tiene la misma información que su clase SiteUser.

Así interior AuthenticateRequest que tendría algo de flujo como

SiteUserSecurityToken sessionToken = null; 
if (TryReadSiteUserSecurityToken(ref sessionToken) && sessionToken != null) 
{ 
    // Call functions to attach my principal. 
} 
else 
{ 
    if (HttpContext.Current.User != null && 
     HttpContext.Current.User.Identity.IsAuthenticated && 
     HttpContext.Current.User.Identity is FormsIdentity) 
    { 
     // Get my SiteUser object 

     // Create SiteUserSecurityToken 

     // Call functions to attach my principal. 
    } 
} 

Y la función de adjuntar al director contendría algo así como

HttpContext.Current.User = sessionSecurityToken.ClaimsPrincipal; 
Thread.CurrentPrincipal = sessionSecurityToken.ClaimsPrincipal; 
this.ContextSessionSecurityToken = sessionSecurityToken; 

Usted querrá asegurarse de que las funciones que escriba el token de seguridad en un cookie add, como mínimo, un valor de suma de comprobación/MAC y, si lo desea, soporte el cifrado con la clave del equipo si está configurado para hacerlo.Las funciones de lectura deben validar estos valores.

+0

Eso es excelente, gracias. ¡Un error de colegial de mi parte! Muchas gracias. –

1

Esto suena como un trabajo para un custom Authorization Filter.

+0

Lo consideré pero me gustaría poder usar mi objeto de usuario fuertemente tipado de otras maneras también. Esperaba no tener que producir un filtro de autorización personalizado y luego comenzar a cablear mis objetos de usuario en una clase de controlador base personalizado, pero parece que podría ser el camino a seguir. Realmente no quiero implementar un proveedor de membresía personalizado tampoco. Gracias por la sugerencia de todos modos :) Parece que es el enfoque que me veré obligado a tomar. –

+0

Si explica * por qué * está inyectando un principal personalizado, quizás haya otras formas de resolver su problema, más ASP.NET MVC. – bzlm

Cuestiones relacionadas