禁用子文件夹或虚拟目录上的表单身份验证

时间:2012-12-12 14:32:31

标签: authentication iis forms-authentication

以下是我的情景:

我在IIS(7.5)中设置了一个使用表单身份验证的网站。我在该网站中有一个子文件夹,我将其用作WebDAV共享。我有一个自定义HTTP模块监视我的WebDAV请求,并且还充当自定义身份验证级别。此自定义身份验证将首先发送HTTP 401 Challenge以在用户尝试将驱动器映射到我的WebDAV共享时获取用户凭据,然后从Basic-Auth头服务器端解析凭据。问题是只有在关闭表单身份验证时才会发送Basic-Auth标头。

通常,当我的HTTP模块找不到Auth Header时,会发送401 Challenge(当Forms Auth关闭时会提示用户输入凭据)。但是,打开Forms Auth后,我的HTTP模块仍会执行并发送401 Challenge,但看起来Forms Auth优先,所以在Fiddler中我可以清楚地看到重定向到:

  

/Account/Login.aspx?ReturnURL=MySubFolder

自定义身份验证的目的是让我在将驱动器映射到WebDAV共享时允许用户登录我的网站。我想捕获他们的网站凭据,对其进行身份验证,然后向他们显示目录的内容。

所以我的问题是:

是否有办法在启用了表单身份验证的网站中的子文件夹或虚拟目录上禁用表单身份验证?

我已经验证我可以通过在我的网站中创建一个新的应用程序并将子文件夹放在那里来解决这个问题,然后在应用程序本身上禁用Forms Auth,但我真的不愿意如果可能的话,这样做。

我尝试过的所有内容(下面列出的内容)都是由于我要求将驱动器映射到Http://localhost/MySubFolder以获得表单身份验证(至少是我认为发生的事情)和重定向到/login.aspx?ReturnUrl=MySubFolder(如Fiddler所示)。

以下是我尝试的内容:

1)MySubFolder中添加了单独的Web.config:

   <configuration>
     <system.web>
       <authorization>
         <allow users="*"/>
       </authorization>
     </system.web>
   </configuration>

2)<location>的根级Web.config中添加了MySubFolder标记,如下所示:

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

3)查看更新IIS中的Feature Delegation

就个人而言,我对上述解决方案有一些疑问,因为从我所读过的内容来看,它们只是允许所有访问,同时仍然启用了表单身份验证。 我需要一种方法来实际在我的子文件夹中禁用表单身份验证。这可能吗?

我还应该注意,我的子文件夹可能是一个虚拟目录,但不需要这样或那样。我只需要在该文件夹上禁用Forms Auth。

根据请求,我的Web.config文件(网站级):

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="MyConnString" connectionString="Persist Security Info=True;Initial Catalog=MyDB;Data Source=MyServer;User ID=UserName;Password=xxxxxxxxxx;MultipleActiveResultSets=True;"/>
  </connectionStrings>
  <system.web>
    <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>
  </system.web>
  <system.webServer>
    <modules runManagedModulesForWebDavRequests="true" runAllManagedModulesForAllRequests="true">
      <add name="CustomWebDAVModule" type="CustomWebDAVModule"/>
    </modules>
  </system.webServer>
</configuration>

3 个答案:

答案 0 :(得分:5)

这个问题已经回答:Multiple/Different authentication settings in web.config

您无法覆盖位置标记内的根身份验证模式=“表单”标记。使文件夹成为自己的应用程序是最简单的方法。

另一种选择是实现自己的自定义Forms身份验证,并让它忽略webdav文件夹的重定向。

<authentication mode="None">

答案 1 :(得分:1)

显然,你有在IIS中正确设置WebDAV。

由于您要使用自定义webdav模块进行身份验证,我们首先需要确保IIS 干扰您的WebDAV请求。

按照以下步骤操作(注意重要的一点是在步骤7中):

  1. 保持web.config原样(在问题中公布)。

  2. 在IIS中启用WebDav。在IIS管理器中选择您的网站。在主窗口中打开WebDAV Authoring Rules

    Open WebDAV Authoring Rules

  3. 在操作窗格(右侧)中,点击Enable WebDAV

    Enable WebDav

  4. 现在选择要为其启用WebDAV的子文件夹(我在我的示例中使用path3),然后单击它,然后打开WebDAV Authoring Rules

    Open WebDAV Authoring Rules for sub-folder

  5. 点击操作窗格(右侧)中的Add authoring rule...

    Click -Add authoring rule...-

  6. 在打开的对话框中,确保选中所有这些内容All contentAll usersReadSourceWrite并点击{ {1}}。这将向具有所有权限的所有用户授予对该子文件夹的所有内容的访问权限。

    Add authoring rule

  7. 现在最重要的部分。由于您希望通过自定义 WebDAV处理程序处理WebDAV身份验证,因此我们必须明确告知IIS 干扰身份验证。我们怎么做?我们告诉IIS允许匿名 WebDAV访问。这样,IIS不会尝试对用户进行身份验证,并且您的模块可以自由执行其授权操作。要执行此操作,我们需要在OK下将Allow Anonymous Property Queries设置为True。接下来的步骤将重点介绍如何执行此操作。

  8. 打开网站根目录WebDav settings

    Open WebDAV Authoring Rules

  9. 点击WebDAV Authoring Rules

    Click -WebDAV settings...-

  10. WebDAV settings...设为Allow Anonymous Property Queries

    Set Allow Anonymous Property Queries

  11. 关闭并重新启动您将要测试的WebDAV客户端。这是为了确保它不会缓存先前错误配置中的连接参数。

  12. 检查您网站的WebDAV配置是否符合要求。 :)

答案 2 :(得分:0)

在自定义HTTP模块中,您可以告诉表单身份验证通过HttpResponse.SuppressFormsAuthenticationRedirect来抑制重定向:

public class DavAuthenticationModule : IHttpModule
{
        public void Init(HttpApplication application)
        {
            application.AuthenticateRequest += App_OnAuthenticateRequest;
        }

        private void App_OnAuthenticateRequest(object source, EventArgs eventArgs)
        {
            // Only applies for WebDAV requests.
            var ctx = HttpContext.Current;
            if (!ctx.Request.Path.StartsWith("/dav/path", StringComparison.OrdinalIgnoreCase))
                return;

            // So that forms auth won't do a redirect.
            // Note that it will still attempt to read / parse the forms auth cookie.
            ctx.Response.SuppressFormsAuthenticationRedirect = true;        

            // Now do my own auth.
            DoBasicHttpAuthentication(ctx);
        }
}

另一种选择是在Forms Auth运行之前挂钩FormsAuthenticationModule.Authenticate事件进行身份验证。这将需要你在IIS中为模块实例捕捉,我没有一个例子。

这两个选项都基于.NET 4.6参考源:http://referencesource.microsoft.com/#System.Web/Security/FormsAuthenticationModule.cs,ac471f8ac73cdb2b