2011-07-13 12 views
6

Tengo un archivo Global.asx que necesita hacer autenticación personalizada, auditar y crear perfiles. Esto es necesario porque admite un sistema SSO basado en SAML y necesita anular la autenticación .Net normal (que no es compatible con SAML o autenticación mixta)¿Buscar un archivo estático durante Application_BeginRequest?

No deseo activarlo para archivos estáticos, como .js, .css, .png, etc.

En Cassini/WebDev e IIS7 lo hace.

Lo que quiero es una simple comprobación, como (que no existe, por desgracia) para identificar los archivos estáticos.

Me doy cuenta de que esto sería bastante simple de escribir, pero se siente como algo que ya debe existir - IIS ya ha aplicado las políticas de almacenamiento en caché para los archivos estáticos, y así sucesivamente.

Necesito una solución de código, en lugar de un cambio de configuración de IIS.

actualización

Ésta es mi solución actual:

/// <summary>Hold all the extensions we treat as static</summary> 
static HashSet<string> allowedExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) 
{ 
    ".js", ".css", ".png", ... 
}; 

/// <summary>Is this a request for a static file?</summary> 
/// <param name="request">The HTTP request instance to extend.</param> 
/// <returns>True if the request is for a static file on disk, false otherwise.</returns> 
public static bool IsStaticFile(this HttpRequest request) 
{ 
    string fileOnDisk = request.PhysicalPath; 
    if (string.IsNullOrEmpty(fileOnDisk)) 
    { 
     return false; 
    } 

    string extension = Path.GetExtension(fileOnDisk); 

    return allowedExtensions.Contains(extension); 
} 

Esto funciona y es lo suficientemente rápido, pero se siente terriblemente torpe. En particular, confiar en extensiones va a ser propenso a errores si agregamos nuevos archivos estáticos en los que no se pensó.

¿Hay una manera mejor sin cambiar la configuración de IIS?

Respuesta

0

Es posible que pueda verificar qué manejador está tratando con la solicitud.

En IIS6, solo los archivos .net, por ejemplo, aspx, se asignan a un controlador que hace cosas.

En IIS7 con la canalización integrada, todo se enruta a través de .net, que normalmente es algo bueno. Sin embargo, los diferentes manejadores todavía tratan con diferentes tipos de archivos. En particular, creo que el manejador de archivos estáticos es el que necesita verificar. La propiedad httpcontext.handler debería permitirle resolverlo.

Se puede crear un método de extensión para agregar ese método isStatic ...

Simon

+0

Me doy cuenta de que podría escribir mi propia implementación (como digo en la pregunta) pero que se siente como volver a inventar la rueda. IIS y .Net ya saben que esta es una solicitud de archivo estático, por lo que debe haber una forma existente de hacerlo. – Keith

0

Hay algunas opciones:

  • Adición authorizationelement y negar ninguno de esos caminos que se no necesita ninguna autenticación y contiene sus archivos estáticos
  • Está utilizando tubería integrada. Apagarlo en su IIS 7.
+0

Tuve que anular por completo el mecanismo de autorización de .Net para admitir SSO de SAML (por eso necesito mucho trabajo en 'Application_BeginRequest' en primer lugar), por lo que está desactivada la opción 1. Además, como dije en la pregunta, cambiar la configuración de IIS no es una opción; necesito una solución de código. – Keith

+0

Lo siento, debería haberlo leído completamente. Actualizará. – Aliostad

0

No hay duda de que es necesario crear un método de extensión personalizada porque el motor de enrutamiento ASP.NET utiliza este código para decidir si un archivo existe,

if (!this.RouteExistingFiles) 
{ 
    string appRelativeCurrentExecutionFilePath = httpContext.Request.AppRelativeCurrentExecutionFilePath; 
    if (((appRelativeCurrentExecutionFilePath != "~/") && (this._vpp != null)) && (this._vpp.FileExists(appRelativeCurrentExecutionFilePath) || this._vpp.DirectoryExists(appRelativeCurrentExecutionFilePath))) 
    { 
      return null; 
     } 
} 

No podrá decidir si la solicitud es estática en Application_BeginRequest utilizando el contexto.controlador porque el Módulo de enrutamiento puede cambiar el controlador y este módulo siempre se ejecuta después de Application_BeginRequest. Mi sugerencia es usar el código similar que utiliza el motor de enrutamiento ASP.NEt.

Cuestiones relacionadas