6

Here is my scenario:

I've got a website set up in IIS (7.5) that uses Forms Authentication. I've got a subfolder within that website that I'm using as a WebDAV share. I've got a custom HTTP Module monitoring my WebDAV requests and also acts as a level of custom authentication. This custom authentication will first send a HTTP 401 Challenge to get the user's credentials when they try to map a drive to my WebDAV share, and then the credentials are parsed out of the Basic-Auth header server-side. The problem is that a Basic-Auth header is only sent if Forms Authentication is turned off.

What's more is that normally when my HTTP Module doesn't find an Auth Header, a 401 Challenge is sent (which prompts the user for credentials when Forms Auth is turned off). However, with Forms Auth turned on, my HTTP Module still executes and sends a 401 Challenge, but it appears that the Forms Auth is taking priority so in Fiddler I can clearly see a redirect to:

/Account/Login.aspx?ReturnURL=MySubFolder

The point of the custom authentication is so that I can allow the user to log-in to my site when mapping a drive to my WebDAV share. I want to capture their website credentials, authenticate them, and then show them the contents of the directory.

So my question is:

Is there a way to get Forms Authentication disabled on a subfolder or Virtual Directory within a website which has Forms Authentication enabled?

I've verified that I can get around this by creating a new Application in my website and put the subfolder in there, and then disable Forms Auth on the Application itself, but I'd really prefer not to do that if possible.

Everything I've tried (listed below) has resulted with my request to map a drive to Http://localhost/MySubFolder getting taken over by Forms Authentication (at least that's what I think is happening) and redirected to /login.aspx?ReturnUrl=MySubFolder (as shown in Fiddler).

Here's what I've tried:

1) Added a separate Web.config in MySubFolder:

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

2) Added a <location> tag in the root-level Web.config for MySubFolder like this:

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

3) Looked at updating the Feature Delegation in IIS.

Personally, I had some doubt with the above solutions because from what I've read, they are meant to simply allow all access while still leaving Forms Authentication enabled. I need a way to actually get Forms Authentication disabled on my subfolder. Is this possible?

I should also note that my subfolder could be a Virtual Directory, but it's not required one way or the other. I just need a way for Forms Auth to be disabled on that folder.

As per request, my Web.config file (site-level):

<?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>
Community
  • 1
  • 1
lhan
  • 4,585
  • 11
  • 60
  • 105
  • Can you post your `web.config` file. Please take care to obfuscate critical information like db user credentials etc when posting. – Tanzeel Kazi Dec 28 '12 at 09:23
  • Thanks for the comment, @TanzeelKazi. I've looked into this further, and was able to narrow my question down to be more specific. I've also listed my entire Web.config, which is very minimal in my testing set-up. Please let me know if I can provide any further information! – lhan Dec 28 '12 at 15:06
  • I couldn't for the life in me figure out why my MVC application was stripping the virtual directory name when forwarding to the login url. Turns out i missed the ~. – Stuart Oct 04 '15 at 10:30

3 Answers3

5

This question has already been answered: Multiple/Different authentication settings in web.config

You can't override the root authentication mode="Forms" tag within location tags. Making the folder it's own application is the easiest way out.

Another option is to implement your own custom Forms authentication and have it ignore the redirect for your webdav folder.

<authentication mode="None">
Community
  • 1
  • 1
Louis Ricci
  • 20,804
  • 5
  • 48
  • 62
  • Thank you. I've made the folder it's own application as I haven't found another solution. – lhan Apr 02 '13 at 14:49
1

Apparently you have not correctly setup WebDAV within IIS.

Since you want to use a custom webdav module for authentication we first need to ensure that IIS does not interfere with your WebDAV requests.

Follow these steps (note that the important point is in step 7):

  1. Keep your web.config as is (as posted in the question).

  2. Enable WebDav within IIS. Within the IIS manager select your website. Within the main window open WebDAV Authoring Rules.

    Open WebDAV Authoring Rules

  3. In the actions pane (on the right) click Enable WebDAV.

    Enable WebDav

  4. Now select your sub-folder that you want to enable WebDAV for (I am using path3 in my example) by clicking it and then open WebDAV Authoring Rules.

    Open WebDAV Authoring Rules for sub-folder

  5. Click Add authoring rule... in the actions pane (on the right).

    Click -Add authoring rule...-

  6. In the dialog that opens make sure all of these are selected All content, All users, Read, Source and Write and click OK. This will grant access to all content of that subfolder to all users with all permissions.

    Add authoring rule

  7. Now the most important part. Since you want to handle WebDAV authentication through your custom WebDAV handler we must explicitly tell IIS not to interfere with authentication. How do we do that? We tell IIS to allow anonymous WebDAV access. This way IIS does not try to authenticate the user and your module is free to do its authorization operations. To go about doing this we will need to set Allow Anonymous Property Queries to True under WebDav settings. The next steps will highlight how to do this.

  8. Open the site root WebDAV Authoring Rules.

    Open WebDAV Authoring Rules

  9. Click WebDAV settings....

    Click -WebDAV settings...-

  10. Set Allow Anonymous Property Queries to True.

    Set Allow Anonymous Property Queries

  11. Close and restart the WebDAV client that you will be testing on. This is to ensure that it does not cache connection parameters from the previous incorrect configuration.

  12. Check to see if the WebDAV configuration of your website works as desired. :)

Tanzeel Kazi
  • 3,797
  • 1
  • 17
  • 22
  • Thanks again, but this didn't work. Same issue as before I can see it going through my module and sending the Challenge response, but it never prompts for credentials. I should also note that the requests coming in to my WebDAV share (as seen in Fiddler) are identical when Forms Auth is enabled or disabled. The problem is that when Forms Auth is enabled, there is another request sent immediately after to "/Account/Login.aspx?ReturnURL=MySubFolder", so it seems Forms Auth is still interfering somehow? – lhan Dec 28 '12 at 15:23
  • @lhan16 It seems like the WebDAV module is interfering with forms authentication for your requests. I'll think some more over this and get back to you later (hopefully with a working solution). – Tanzeel Kazi Dec 28 '12 at 15:33
  • Do you think it's the built-in IIS WebDAV module or my custom module? My custom module appears to be functioning normally - so if you mean the IIS module, that sounds like a pretty good guess :) I'll keep looking into it as well! – lhan Dec 28 '12 at 15:38
  • @lhan16 Yes I believe that it is the built-in module that is interfering with your request but I also think it is just a configuration issue. See if my updated answer helps. :) – Tanzeel Kazi Dec 28 '12 at 20:02
  • Thanks, however the only thing I had set up differently from your answer was that I had my WebDAV authoring rule set up at the site level, and not just on my subfolder (although when it's at the site level, my subfolder inherits it anyway). I think it's probably better to set it at the subfolder level like you have mentioned, but in Fiddler, I'm still seeing a redirect to my Login.aspx page when I try to map a drive to my subfolder, with no prompt for credentials. – lhan Dec 28 '12 at 21:12
  • In regards to #7 in your answer, I believe Anonymous should already be "allowed" since I've got Anonymous and Forms authentication enabled at the site level - it's just that my custom authentication when mapping drives only seems to work when I disable Forms Auth. – lhan Dec 28 '12 at 21:17
  • @lhan16 That's not true. You need to enable it at the WebDAV settings also otherwise it doesn't work. I tested it on my local setup. I don't get the same error but I do get a `401 Unauthorized` error if I don't configure the WebDAV setting. Do give it a shot. – Tanzeel Kazi Dec 28 '12 at 22:05
  • Sorry I didn't specify - I did have that setting applied already, that last comment was more "thinking out loud" :) It does still appear that Forms Auth is taking precedent though since I'm seeing a redirect to my login page in Fiddler. – lhan Dec 28 '12 at 22:16
  • @lhan16 OMG.. Looks like you've got the mother of all configuration issues. :P – Tanzeel Kazi Dec 28 '12 at 22:47
1

Within your custom HTTP Module, you can tell the Forms Authentication to supress the redirect via 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);
        }
}

Another option is to hook the FormsAuthenticationModule.Authenticate event to authenticate before Forms Auth runs at all. This would require you to fish around in IIS for the module instance, which I don't have an example for.

Both these options are based on the .NET 4.6 reference source: http://referencesource.microsoft.com/#System.Web/Security/FormsAuthenticationModule.cs,ac471f8ac73cdb2b

ligos
  • 4,256
  • 2
  • 25
  • 34
  • This answer really helped me when trying to get ASP.Net Forms Auth and OWIN Auth to play nicely together on an Umbraco project, without Forms always taking over when OWIN did a challenge - thank you! – Martin Rhodes Mar 16 '20 at 14:27