3

I'm trying to POST data from my Angular 2 service to ASP.NET 5 API that uses windows authentication and is hosted on IIS. After some modification to angular, requests are created with:

var request = new XMLHttpRequest();
request.withCredentials = true;

That's solved my problem with authorizing GET requests, now for a first GET request, server returns 401 response with headers:

WWW-Authenticate:Negotiate
WWW-Authenticate:NTLM

And after that angular client sends an another request, but this time with a Authorization header that contains NTLM token and it works.

For POST request I added "Content-Type: application/json" to request's header, so browser sends a first request like this:

OPTIONS /api/reservation/ HTTP/1.1
Host: localhost:82
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:81
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Referer: http://localhost:81/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4

And server responds with:

HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.5
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Wed, 13 Jan 2016 11:54:56 GMT
Content-Length: 6394

But this time, instead of another request with authorization, like in GET request, there's an error:

XMLHttpRequest cannot load http://localhost:82/api/reservation/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:81' is therefore not allowed access. The response had HTTP status code 401.

For CORS I use this configuration in ASP.NET 5:

services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin().AllowAnyMethod().WithHeaders("accept", "authorization", "content-type", "origin", "x-custom-header").AllowCredentials()));

Can I somehow disable windows authentication for OPTIONS requests in IIS? Or maybe there's some way to force browser to follow up with authorization?

Adiqq
  • 463
  • 6
  • 19
  • Can you provide more information on how you got the GET request to work? I am setting withCredentials = true using angular's http.get headers but it seems like an authorization header/token is never sent. – alrm3000 Jan 24 '17 at 21:34
  • It was quite hacky, but I replaced implementation of [BrowserXhr](https://github.com/angular/angular/blob/master/modules/%40angular/http/src/backends/browser_xhr.ts) and registered it in Angular DI. – Adiqq Jan 25 '17 at 09:15

1 Answers1

4

Ok, I found a way to make it work on IIS Express or IIS 8.5, with ASP.NET 5.

We need to modify wwwroot/web.config like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
    </handlers>
    <httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600" forwardWindowsAuthToken="true"></httpPlatform>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Request-Headers" value="Content-Type,Authorization" />
        <add name="Access-Control-Allow-Headers" value="Content-Type,Authorization" />
        <add name="Access-Control-Allow-Origin" value="http://localhost:5814" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
    <security>
      <authorization>
        <!--<remove users="*" roles="" verbs="" />  Uncomment for IIS-->
        <add accessType="Allow" users="*" verbs="GET,POST,PUT" />
        <add accessType="Allow" users="?" verbs="OPTIONS" />
        <add accessType="Deny" users="?" verbs="GET,POST,PUT" />
      </authorization>
    </security>
  </system.webServer>
  <system.web>
    <authorization>
      <allow users="*" verbs="GET,POST,PUT" />
      <allow users="?" verbs="OPTIONS" />
    </authorization>
  </system.web>
</configuration>

In launchSettings.json set:

"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iisExpress": {
  "applicationUrl": "http://localhost:4402/",
  "sslPort": 0
}

And in Startup.cs:

services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyMethod().WithHeaders("accept", "authorization", "content-type", "origin", "x-custom-header").AllowCredentials()));

Some of these settings might be not neccesary.

For IIS we need to install Windows Authentication and URL Authorization.

Adiqq
  • 463
  • 6
  • 19
  • 2
    Anonymous Authentication had to be allowed with cors enabled (app.UseMvc() has to be after app.UseCors() of course) so it doesn't try to authenticate cors preflight check. web.config doesn't need to be modified. – pajics Mar 27 '17 at 10:05
  • Its true! I had the same issue, and my web.config did not have to be changed. I just enabled Anonymous Authentication and POST requests did also work. Thanks! – David Jun 20 '17 at 07:40
  • @pajics I know its very late to ask.. But in the case of Web forms what to do (Not MVC) – Sandeep Thomas Mar 26 '20 at 05:34
  • @SandeepThomas unfortunately I can't help you with that, but maybe this SO link can: https://stackoverflow.com/questions/35627648/cors-endpoints-on-asp-net-webforms-webmethod-endpoints – pajics Mar 27 '20 at 06:06