4

I am using angular 4 with ASP.NET web api 2 on backend with windows authentication enabled. I have one post and one get api. GET works fine. But for POST I am getting this error

Response for preflight has invalid HTTP status code 401

Which means I am getting unauthorised error for OPTIONS method which I know should not be the case because, OPTIONS method is never called with user credentials.

in angular I am calling api as follows

      let requestOptions = new RequestOptions({
      withCredentials: true,
      headers: new Headers({
        'content-type': 'application/json'
      })
    })
    this.http.post("someapiendpoint", JSON.stringify(data), requestOptions).subscribe(data => {
      debugger;
    });

I have set all CORS header in my web config as follows

        <add name="Access-Control-Expose-Headers " value="WWW-Authenticate"/>
        <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
        <add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />

Also I have following in my authentication block of web.config

             <authentication>

                <anonymousAuthentication enabled="false" userName="" />

                <basicAuthentication enabled="false" />

                <clientCertificateMappingAuthentication enabled="false" />

                <digestAuthentication enabled="false" />

                <iisClientCertificateMappingAuthentication enabled="false">
                </iisClientCertificateMappingAuthentication>

                <windowsAuthentication enabled="true">
                    <providers>
                        <add value="Negotiate" />
                        <add value="NTLM" />
                    </providers>
                </windowsAuthentication>

            </authentication>

I tried removing

headers: new Headers({
            'content-type': 'application/json'
          })

Following is my controller code for web api

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace Backend.Controllers
{
    public class DemoController : ApiController
    {
        Entities db = new Entities();
        public DemoController ()
        {
        }

        [HttpPost]
        [ActionName("postevent")]
        public IHttpActionResult PostEvent(Demo data)
        {
            db.Demos.Add(data);
            db.SaveChanges();
            return Ok();
        }

    }
}

from my angular code but it did not help. I also tried to replace it with 'text/html' but that did not work too. Can some one tell me what wrong am I doing. As I assume it should work fine if it is working for GET.

nikhil mehta
  • 972
  • 15
  • 30

2 Answers2

3

All the topics I've read state that you cannot disable anonymous authentication completely otherwise the OPTIONS pre-flight request will not work. This is because:

According W3C specifications, browser excludes user credentials from CORS preflight:

Please see this topic for example: WebAPI CORS with Windows Authentication - allow Anonymous OPTIONS request

Basically the solution is to allow OPTIONS calls to pass through without authentication. And for this to be possible Anonymous Authentication needs to be enabled.

In this question: 401 response for CORS request in IIS with Windows Auth enabled The answer suggests the following web.config

<system.web>
  <authentication mode="Windows" />
    <authorization>
      <allow verbs="OPTIONS" users="*"/>
      <deny users="?" />
  </authorization>
</system.web>
Sal
  • 5,129
  • 5
  • 27
  • 53
  • No this did not help – nikhil mehta Aug 04 '17 at 07:08
  • 1
    I have found that this fix works fine. Using IIS i had to enable both anonymous and windows authentication. Then add the authentication/authorization settings above to the web.config. After that any OPTIONS requests send by angular to my API website were passed through successfully. – Stuart Jun 13 '18 at 13:21
2

Paul's answer is correct. I have the exact same setup and it works fine.

You need to make sure to enable both Anonymous and Windows Authentication, add the snippet from Paul's answer to the web.config to allow unauthenticated OPTIONS requests, and add the [Authorize] attribute on your controller.

Andrei Matracaru
  • 3,511
  • 1
  • 25
  • 29