2010-08-02 39 views
6

所以,我有网络应用程序,象这样web.configs:确定当前页面是否需要授权?

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

换句话说,大多数页面需要身份验证和授权,但有些却没有。

然后我有一个IHttpModule将被所有不同的应用程序使用。我想要做的就是检查当前请求是否“安全”。如果页面不需要授权,我不希望我的IHttpModule做任何事情。我正在使用FormsAuthentication,并且我认为FormsAuthentication已经将所有这些信息缓存在某处,不是吗?此外,由于此检查将不断运行,所以它必须非常快速。

我目前正在订阅HttpApplication.AuthorizeRequest,但令人惊讶的是,即使对于允许匿名访问的资源,此事件也会触发。

任何想法?谢谢阅读!

回答

4

创建一个bootleg IPrincipal,然后你必须使用它。如果盗版主体有权访问,则允许匿名访问。

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创建一个单身的IPrincipal实例。非常有用的一段代码。但是,它不需要创建一个'UrlAuthorizationModule'的实例。只需使用静态方法'CheckUrlAccessForPrincipal'就足够了。 – 2014-10-19 20:18:39

0

我想如果服务器返回响应401未授权状态码,资源可能需要授权。但有时服务器可能会重定向到登录页面,所以这种方法不是很可靠。

0

derp!

HttpContext.Current.SkipAuthorization 
+0

其实,没关系。对于我在web.config中设置的授权排除,这始终是错误的。只有Login.aspx和WebResource.axd等页面将此属性设置为true。投票我的回答 – 2010-08-02 19:33:58

0

一种更直接的方法是这样的:

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

使用此之前,请确保您的网站有权限来执行反射。

<咆哮>

我永远无法理解为什么微软隐藏的这么多使用他们的API的“内部”(这样的方法)。在我看来,如果微软必须在内部暴露某些东西,那么机会就是某个人,在某个地方也会需要它。

< /兰特>

7

而是创建一个盗版主/身份,你可以只使用一个通用的身份。

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