9

I searched a lot on Google and Stack overflow to find a solution for my problem, but nothing worked.

Here is my problem:

  • I use IIS 7 with a special programming environment called WebDEV that does not allow direct manipulation of OPTIONS HTTP method. So, all solutions suggesting some kind of server-side request handling using code are not feasible.

  • I have to use Window authentication and disable anonymous access

  • I have a page that uses CORS to POST to this server. As this POST should have Content-type: Octet-stream, a preflight is issued by the browser.

  • When I enable anonymous access, everything works fine (CORS is well configured)

  • When I disable anonymous access, the server replies with HTTP 401 unauthorized response to the preflight request, as it does not contain credentials information.

  • I tried to write a module for IIS that accepts OPTIONS requests like this, but it did not work (couldn't add the module correctly to IIS, maybe)

    public class CORSModule : IHttpModule
       {
    
              public void Dispose() { 
              }
    
              public void Init(HttpApplication context)
              {
                   context.PreSendRequestHeaders += delegate
                   {
                      if (context.Request.HttpMethod == "OPTIONS")
                       {
                             var response = context.Response;
                             response.StatusCode = (int)HttpStatusCode.OK;
                       }
                   };
              }
        } 
    

The question is: How can I make IIS respond with HTTP 200 to the preflight request without enabling anonymous access or writing some server-side code? Is there an easy configuration or a ready-made module for IIS to do so? At least, what are the detailed steps to install the above module into IIS 7?

AhmadWabbi
  • 2,203
  • 1
  • 19
  • 30

4 Answers4

7

Here is the solution that uses "URL Rewrite" IIS module. It works perfectly.

1- Stop IIS service (maybe not necessary)

2- Install "web platform installer" from https://www.microsoft.com/web/downloads/platform.aspx

3- Go to "Applications" tab and search for "URL Rewrite" and download it

4- Install this hotfix KB2749660 (maybe not necessary)

5- Open IIS configuration tool, double click "URL Rewrite"

6- Add a new blankrule

7- Give it any name

8- In "Match URL", specify this pattern: .*

9- In "Conditions", specify this condition entry: {REQUEST_METHOD} and this pattern: ^OPTIONS$

10- In "Action", specify: action type Personalized response, state code 200, reason Preflight, description Preflight

11- Start the server

Now, the server should reply with a 200 status code response to the preflight request, regardless of the authentication.

Remarks: I also disabled all compression, I don't know if it matters.

AhmadWabbi
  • 2,203
  • 1
  • 19
  • 30
  • 2
    life saver bro +1 – Rob Scott Oct 04 '17 at 16:05
  • Later Microsoft shipped official CORS module for IIS, https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference so this workaround is no longer needed. – Lex Li Sep 03 '18 at 14:24
  • @LexLi Well, great! – AhmadWabbi Sep 04 '18 at 15:19
  • Has anyone actually managed to get the CORS Module to work? I've read 100 different articles but absolutely nothing works. It seems totally impossible to do a very basic AJAX request if you have Windows Authentication enabled. It's utterly ridiculous! – Chris Gilbert Oct 21 '20 at 14:59
  • @ChrisGilbert This is why I am still using the URL Rewrite module :) – AhmadWabbi May 27 '21 at 15:09
4

From AhmadWabbi's answer, easy XML pasting into your web.config:

<system.webServer>
    <rewrite>
        <rules>
            <rule name="CORS Preflight Anonymous Authentication" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{REQUEST_METHOD}" pattern="^OPTIONS$" />
                </conditions>
                <action type="CustomResponse" statusCode="200" statusReason="Preflight" statusDescription="Preflight" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>
DoubleJ
  • 321
  • 4
  • 6
0

In order for your module to take precedence it will have to override any modules within IIS that may interfere. For instance, your web.config may need a or enable anonymous, and create an attribute for intercepting the traffic and filtering through as you need to.

Anthony Mason
  • 167
  • 1
  • 12
0

All the answers that involve writing code, using the rewrite module, or hard-coding values in web.config were correct when they were written, but I believe the correct answer to this problem in 2020 is to use the official IIS CORS module. This will handle all the little gotchas like having to allow unauthenticated OPTIONS requests, without otherwise supporting unauthenticated users.

This related answer has some really great details about using this module, but the simplest configuration is right at the top:

  <system.webServer>
    <cors enabled="true">
      <add origin="*" allowCredentials="true" />
    </cors>
  </system.webServer>

I would certainly change the origin="*" to the specific origin you expect to use the API from. You can have more than one <add> tag, and the linked answer shows how to customize allowed headers, methods, etc. for each.

James B
  • 243
  • 2
  • 11