2010-08-02 3 views
6

Also, ich habe Web-Anwendungen mit web.configs wie so:Ermitteln, ob die aktuelle Seite eine Autorisierung erfordert?

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

Mit anderen Worten, die meisten Seiten erfordern eine Authentifizierung und Autorisierung, einige aber auch nicht.

Dann habe ich ein IHttpModule, das von allen verschiedenen Anwendungen verwendet wird. Alles, was ich tun möchte, ist zu überprüfen, ob die aktuelle Anfrage überhaupt "gesichert" ist. Wenn die Seite keine Autorisierung erfordert, möchte ich nicht, dass mein IHttpModule überhaupt etwas tut. Ich verwende FormsAuthentication und nehme an, dass FormsAuthentication diese Informationen bereits irgendwo zwischengespeichert hat, oder? Da diese Prüfung ständig ausgeführt wird, muss sie sehr schnell sein.

Ich abonniere derzeit die HttpApplication.AuthorizeRequest, aber dieses Ereignis wird überraschend auch für Ressourcen ausgelöst, die anonymen Zugriff ermöglichen.

Irgendwelche Ideen? Danke fürs Lesen!

Antwort

4

Erstellen Sie ein Bootleg IPrincipal und dann müssen Sie das verwenden. Wenn der Bootleg Principal Zugriff hat, ist der anonyme Zugriff erlaubt.

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 zum Erstellen einer Singleton IPrincipal-Instanz. Sehr nützliches Stück Code. Es muss jedoch keine Instanz von "UrlAuthorizationModule" erstellt werden. Es genügt, die statische Methode 'CheckUrlAccessForPrincipal' zu verwenden. –

0

Ich denke, wenn Server Antwort mit 401 Unauthorized Statuscode zurückgibt, benötigt Ressource möglicherweise eine Autorisierung. Aber manchmal kann der Server zur Anmeldeseite umleiten, daher ist diese Methode nicht sehr zuverlässig.

0

derp!

HttpContext.Current.SkipAuthorization 
+0

Eigentlich, vergiss es. Dies ist immer falsch für meine Autorisierungsausschlüsse in der web.config. Nur Seiten wie Login.aspx und WebResource.axd haben diese Eigenschaft auf True festgelegt. Down vote meine Antwort –

0

Ein direkterer Ansatz ist die folgende:

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

Vor diesem verwenden, stellen Sie sicher, dass Ihre Web-Site-Berechtigungen Reflexion zu erfüllen hat.

< Rant>

Ich habe nie verstanden, warum Microsoft hides so viel von ihrer API "intern" (wie diese Methode). Meiner Meinung nach, wenn Microsoft intern etwas aufdecken musste, dann sind die Chancen, dass jemand es auch braucht.

</Rant>

7

Statt eine Bootleg Haupt/Identität zu schaffen, können Sie nur eine generische Identität nutzen.

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