Determine if authorization of the current page is required?

So, I have web applications with these web applications:

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

In other words, most pages require authentication and authorization, but some of them do not work.

Then I have an IHttpModule that will be used by all the various applications. All I want to do is check if the current request is really β€œprotected”. If the page does not require authorization, I do not want my IHttpModule to do anything at all. I use FormsAuthentication, and I assume that FormsAuthentication already has all this information cached somewhere, right? In addition, since this check will work continuously, so it should be very fast.

I am currently subscribing to HttpApplication.AuthorizeRequest, but surprisingly this event fires even for resources that allow anonymous access.

Any ideas? Thanks for reading!

+6
forms-authentication
source share
5 answers

Create a bootleg IPrincipal and then you should use this. If the bootleg principal has access, anonymous access is allowed.

 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 } } } 
+4
source share

Instead of creating a master / bootleg identifier, you can simply use a common identifier.

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

I think that if the server returns a response with 401 unauthorized status codes, the resource may need authorization. But sometimes the server can redirect to the login page, so this method is not very reliable.

0
source share

Derp!

 HttpContext.Current.SkipAuthorization 
0
source share

A more direct approach is as follows:

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

Before using this, make sure your website has permission to reflect.

<Rent>

I never understood why Microsoft hides so much of its API using "internal" (like this method). In my opinion, if Microsoft had to expose something inside, then the chances are someone, somewhere else it will be needed.

</ Rent>

0
source share

All Articles