2010-08-02 14 views
6

lo tanto, tengo aplicaciones web con web.configs, así:¿Determina si la página actual requiere autorización?

<authorization> 
    <deny users="?"/> 
</authorization> 
... 
<location path="SomeUnsecuredPage.aspx"> 
    <system.web> 
    <authorization> 
     <allow users="*"/> 
    </authorization> 
    </system.web> 
</location> 

En otras palabras, la mayoría de las páginas requieren autenticación y autorización, pero algunos no lo hacen.

Luego tengo un IHttpModule que será utilizado por todas las diferentes aplicaciones. Todo lo que quiero hacer es verificar si la solicitud actual está "segura". Si la página no requiere autorización, no quiero que mi IHttpModule haga nada. Estoy utilizando FormsAuthentication y supongo que FormsAuthentication ya tiene toda esta información almacenada en algún lugar, ¿no? Además, dado que esta comprobación se ejecutará constantemente, debe ser muy rápida.

Actualmente estoy suscrito a HttpApplication.AuthorizeRequest, pero sorprendentemente este evento se dispara incluso para los recursos que permiten el acceso anónimo.

¿Alguna idea? ¡Gracias por leer!

Respuesta

4

Crea un IPrincipal de bootleg y luego tienes que usar eso. Si el principal del bootleg tiene acceso, entonces se permite el acceso anónimo.

public static class AnonymousAccessCheck 
      { 
       public static bool IsAnonymousAccessAllowed(HttpRequest request) 
       { 
        // unfortunately checking if a page allows anonymous access is more complicated than you'd think(I think). 
        // here we have to create a "Fake" IPrincipal that will only ever have access to 
        // pages that allow anonymous access. That way if our fake principal has access, 
        // then anonymous access is allowed 

        UrlAuthorizationModule urlAuthorizationModule = new UrlAuthorizationModule(); 
        return UrlAuthorizationModule.CheckUrlAccessForPrincipal(request.Path, AnonymousPrincipal.Instance, request.RequestType); 
       } 

       private class AnonymousPrincipal : IPrincipal 
       { 
        private static AnonymousPrincipal _Instance; 
        public static AnonymousPrincipal Instance 
        { 
         get 
         { 
          if (_Instance == null) 
           _Instance = new AnonymousPrincipal(); 

          return _Instance; 
         } 
        } 

        private AnonymousPrincipal() 
        { 
         _Identity = new AnonymousIdentity(); 
        } 

        private readonly IIdentity _Identity; 

        #region IPrincipal Members 

        public IIdentity Identity 
        { 
         get { return _Identity; } 
        } 

        public bool IsInRole(string role) 
        { 
         return false; 
        } 

        #endregion 

        private class AnonymousIdentity : IIdentity 
        { 
         #region IIdentity Members 
         public string AuthenticationType 
         { 
          get { return string.Empty; } 
         } 

         public bool IsAuthenticated 
         { 
          get { return false; } 
         } 

         public string Name 
         { 
          get { return string.Empty; } 
         } 
         #endregion 
        } 
       } 
      } 
+0

+1 para crear una instancia de IPrincipal singleton. Pieza de código muy útil. Sin embargo, no es necesario crear una instancia de 'UrlAuthorizationModule'. Solo usar el método estático 'CheckUrlAccessForPrincipal' es suficiente. –

0

Creo que si el servidor devuelve la respuesta con el código de estado 401 no autorizado, el recurso puede requerir autorización. Pero a veces el servidor puede redirigir a la página de inicio de sesión, por lo que este método no es muy confiable.

0

derp!

HttpContext.Current.SkipAuthorization 
+0

En realidad, nunca importa. Esto siempre es falso para mis exclusiones de autorización establecidas en web.config. Solo las páginas como Login.aspx y WebResource.axd tienen esta propiedad establecida en verdadero. Abajo vote mi respuesta –

0

Un enfoque más directo es el siguiente:

var method = typeof(UrlAuthorizationModule).GetMethod("RequestRequiresAuthorization", BindingFlags.NonPublic | BindingFlags.Static); 
var requiresAuthentication = (Boolean)method.Invoke(null, new object[] { HttpContext.Current }); 

Antes de utilizar este, asegúrese de que su sitio web tiene permisos para realizar la reflexión.

< Rant>

nunca he entendido por qué Microsoft piel de gran parte de su API usando "interno" (como este método). En mi opinión, si Microsoft tuvo que exponer algo internamente, lo más probable es que alguien, en alguna parte, lo necesite también.

</Rant>

7

En lugar de crear un director de contrabando/identidad sólo puede utilizar una identidad genérica.

public bool IsAnonymousAccessAllowed() 
{ 
    return UrlAuthorizationModule.CheckUrlAccessForPrincipal(Request.Path, new GenericPrincipal(new GenericIdentity(""), new string[0]), Request.RequestType); 
} 
Cuestiones relacionadas