【问题标题】:How do I protect static files with ASP.NET form authentication on IIS 7.5?如何在 IIS 7.5 上使用 ASP.NET 表单身份验证保护静态文件?
【发布时间】:2011-02-23 14:26:37
【问题描述】:

我有一个网站在 IIS 7.5 服务器上运行,在共享主机上使用 ASP.NET 4.0,但完全信任。

该站点是一个基本的“文件浏览器”,允许访问者登录并显示可供他们使用的文件列表,并且显然还可以下载文件。静态文件(主要是 pdf 文件)位于站点上名为 data 的子文件夹中,例如http://example.com/data/...

该站点使用 ASP.NET 表单身份验证。

我的问题是:如何让 ASP.NET 引擎处理对数据文件夹中静态文件的请求,以便文件请求通过 ASP.NET 身份验证,并且用户无法深层链接到一个文件并抓取他们不允许拥有的文件?

【问题讨论】:

    标签: asp.net authentication iis-7 iis-7.5


    【解决方案1】:

    如果您的应用程序池在集成模式下运行,那么您可以执行以下操作。

    将以下内容添加到您的顶级 web.config。

      <system.webServer>
        <modules>
          <add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" />
          <remove  name="UrlAuthorization" />
          <add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />
          <remove  name="DefaultAuthentication" />
          <add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" />
        </modules>
      </system.webServer>
    

    现在您可以在 web.config 中使用标准 ASP.NET 权限来强制对目录中的所有文件进行表单身份验证。

    <system.web>
        <authorization>
            <deny users="?" />
        </authorization>
        <authentication mode="Forms" />
    </system.web>
    

    【讨论】:

    • 谢谢乔尔。不过是评论。我不允许使用不在站点根目录的 web.configs 中的“身份验证”部分,无论如何它似乎适用于用户。但是,当我有 时,我无法让它工作,他们不会进行身份验证,但是如果我将用户明确添加到允许列表并拒绝所有其他经过身份验证的用户,它就可以工作。我是否在 webServer 模块部分中遗漏了一些内容以使其与角色和用户一起使用?
    • 呃,谢谢!这不应该那么难弄清楚。现在为我工作。
    • 这可行,但也会阻止登录页面上使用的任何 css/gif 文件。有什么方法可以让它们显示出来?
    • 对这个解决方案要非常小心!这意味着您的所有静态资源都将通过 FormsAuthenticationModule。如果您将其与 cookie 的滑动到期以及静态资源的一些下游缓存结合使用,那么您实际上可能会缓存 auth cookie 并将它们提供给其他用户! medium.com/@flopasquier/…
    【解决方案2】:

    我在让角色进行身份验证时遇到了同样的问题。经过反复试验,我终于可以对@Joel Cunningham 的代码进行小幅编辑:

    <modules runAllManagedModulesForAllRequests="true" >
    

    我使用这两个网站作为参考:http://forums.iis.net/t/1177964.aspxhttp://learn.iis.net/page.aspx/244/how-to-take-advantage-of-the-iis-integrated-pipeline/

    【讨论】:

    • 这只是废话,通过让它工作而你不知道为什么。这会导致很大的性能问题,因为所有托管模块都会捕获所有请求。 @John 的解决方案正是您所需要的。
    • 嘿,我同意@DotNetWise。如果必须,请确保您选择将为所有请求执行的模块,而不是为所有请求运行所有托管模块。例如: - 注意前置条件为空。
    【解决方案3】:

    这是一个旧线程,但我碰巧遇到了与 Egil 相同的问题。这是包含角色的 Joel 修复版本:

    <modules runAllManagedModulesForAllRequests="false">
          <remove name="FormsAuthenticationModule" />
          <add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
          <remove name="UrlAuthorization" />
          <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />
          <remove name="RoleManager" />
          <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
          <remove name="DefaultAuthentication" />
          <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
    </modules>
    

    【讨论】:

      【解决方案4】:

      附录:

      正如@eych 所指出的,接受的答案还阻止访问~/Content 文件夹(或您拥有CSS 的任何位置)和~/Scripts,等等。

      如果你想允许例外——即允许未经身份验证的用户访问某些文件/文件夹——你可以通过location元素来做到这一点。将以下内容添加到web.config

        <location path="Content">
          <system.web>
            <authorization>
              <allow users="*" />
            </authorization>
          </system.web>
        </location>
      

      更新: 另一种解决方案是在默认情况下保持访问权限 - 这将允许访问您的 CSS / JavaScript / 等 - 并将“锁定”(仅)应用于存储静态内容的文件夹:

      <location path="data">
        <system.web>
          <authorization>
            <deny users="?"/>
          </authorization>
        </system.web>
      </location>
      

      警告:在我们的例子(一个 MVC 站点)中,我们需要用[AuthorizeAttribute] 装饰我们所有的控制器操作(登录除外)。无论如何,这是个好主意,但以前没有必要(因为以前 任何 未经授权的请求都被重定向到登录页面)。

      【讨论】:

        【解决方案5】:

        我想知道为什么需要重新添加默认为集成管道添加的模块(使用默认选项),所以我挖得更深一些。

        您需要删除并重新添加模块,因为默认情况下,不会使用默认选项添加模块。它们为向后兼容添加了一个前提条件,以便仅对已注册的 ASP.NET 处理程序处理的内容(例如 .aspx 页面)运行。

        默认如下:

        <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" 
                 preCondition="managedHandler" />
        

        通过删除模块并在没有前提条件的情况下重新添加它们,这些单独的模块会针对每个请求(包括您的静态内容)运行。它比启用runAllManagedModulesForAllRequests 更精细。

        您可以在 IIS 7 引入集成管道时的几篇文章中了解它:

        请注意,第二篇文章(以及@John 的回答)中的模块名称有错别字,在某些时候从FormsAuthenticationModule 更改为FormsAuthentication

        IIS 7.5 到 8.5 中的一组工作模块对我来说如下所示:

        <system.webServer>
          <modules>
            <!-- Re-add auth modules (in their original order) to run for all static and dynamic requests -->
            <remove name="FormsAuthentication" />
            <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
            <remove name="DefaultAuthentication" />
            <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
            <remove name="RoleManager" />
            <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
            <remove name="UrlAuthorization" />
            <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
          </modules>
        </system.webServer>
        

        【讨论】:

        • 可能很明显,但我会指出,根据您的具体情况,您可能不需要所有这些模块(例如,我不需要 RoleManager)并且您可能需要其他具有类似限制的模块,例如作为 System.Web.SessionState.SessionStateModule
        【解决方案6】:

        如果您的应用程序池在经典模式下运行,您可以执行以下操作。您必须为要处理的每个文件扩展名重复这些步骤,但我在这里使用.html

        首先,将页面构建提供程序添加到 Web.config:

        <?xml version="1.0" encoding="UTF-8"?>
        <configuration>
          <system.web> 
            <compilation>
              <buildProviders>
                <add type="System.Web.Compilation.PageBuildProvider" extension=".html"/>
              </buildProviders>
            </compilation>
          </system.web> 
        </configuration>
        

        然后添加一个页面处理程序工厂:

        <?xml version="1.0" encoding="UTF-8"?>
        <configuration>
          <system.web> 
            <httpHandlers>
              <add type="System.Web.UI.PageHandlerFactory" path="*.html" verb="*"/>
            </httpHandlers>
          </system.web> 
        </configuration>
        

        然后添加一个页面处理程序:

        <?xml version="1.0" encoding="UTF-8"?>
        <configuration> 
          <system.webServer>
            <handlers>
              <add scriptProcessor="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" requireAccess="Script" preCondition="classicMode,runtimeVersionv2.0,bitness32" path="*.html" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" name="HtmlHandler-Classic-32" />
              <add scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" requireAccess="Script" preCondition="classicMode,runtimeVersionv2.0,bitness64" path="*.html" verb="GET,HEAD,POST,DEBUG" name="HtmlHandler-Classic-64"/>
            </handlers>
          </system.webServer>
        </configuration>
        

        这对我有用。 (信用:http://www.ifinity.com.au/Blog/EntryId/66/How-To-301-Redirect-htm-or-html-pages-to-DotNetNuke-aspx-pages。)

        【讨论】:

        • 你拯救了这一天!我要在这里解决一件事:64 位处理程序也应该有 modules="IsapiModule"。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多