Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to authorize CORS preflight request on IIS with Windows Authentication

I have an API on ASP.net Core 2 (windows authentication) and a front on angular. I make a cors configuration to querying my backend from the SPA angular, but im blocked in cause of the preflight who are rejected from the IIS server because he don't have identification information.

error message :

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

code side front :

//MY HEADER
private headers = new Headers({
    'Content-Type': 'application/json', 
    'Access-Control-Allow-Credentials':'true',
    'Access-Control-Allow-Origin':'true'
});

//REQUEST
let options = new RequestOptions({headers:this.headers, withCredentials:true});
return this.http.get(this.tasksUrl,options).map(res=>res.json());

code side back : (Startup.cs)

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors();
   services.AddCors(options =>
   {
       options.AddPolicy("AllowSpecificOrigin",
            builder =>
            {
               builder.WithOrigins("http://theURLofTheFront:8080" )
               .AllowAnyMethod()
               .AllowAnyHeader()
               .AllowCredentials();
            });
   });
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        app.UseCors("AllowSpecificOrigin");
        app.UseMvc();
    }

I try this :

CORS preflight request returning HTTP 401 with windows authentication.

and i added custom header to specify the 'Acces-control-allow-origin' on IIS, dont work for me.

and this dont work for me : https://blogs.msdn.microsoft.com/friis/2017/11/24/putting-it-all-together-cors-tutorial/

I can't remove the default authorization rule.

I thank you in advance for you

like image 849
FRZ7 Avatar asked Mar 23 '18 13:03

FRZ7


People also ask

How do I solve CORS issue in IIS?

Enable CORS Using IIS Manager Navigate to the website you need to edit the response headers for. A dialog box will open. For name enter "Access-Control-Allow-Origin" and for Value enter an asterisk ( * ). Click Ok, you are done.

How do I enable cross-origin request CORS in asp net core?

There are three ways to enable CORS: In middleware using a named policy or default policy. Using endpoint routing. With the [EnableCors] attribute.

How do I enable cross-origin requests in Web API?

To enable cross-origin requests, add the [EnableCors] attribute to your Web API controller or controller method: [EnableCors(origins: "http://example.com", headers: "*", methods: "*")] public class TestController : ApiController { // Controller methods not shown... }


1 Answers

There are several ways to accomplish this, other answers can be found on this similar question --> Angular4 ASP.NET Core 1.2 Windows Authentication CORS for PUT and POST Gives 401


CORS Module

It is possible to configure IIS by using the CORS Module.
As seen here: https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
And further information available here: https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module

The IIS CORS module is designed to handle the CORS preflight requests before other IIS modules handle the same request. The OPTIONS requests are always anonymous, so CORS module provides IIS servers a way to correctly respond to the preflight request even if anonymous authentification needs to be disabled server-wise.

You will need to enable the CORS Module via the Webconfig:

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <cors enabled="true">
      <add origin="*" allowCredentials="true" />
    </cors>
  </system.webServer>
</configuration>

for more granular control:

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <cors enabled="true">
      <add origin="https://readonlyservice.constoso.com" allowCredentials="true">
        <allowMethods>
            <add method="GET" />
            <add method="HEAD" />
        </allowMethods>
        <allowHeaders>
            <add header="content-type" /> 
            <add header="accept" /> 
        </allowHeaders>
      </add>
      <add origin="https://readwriteservice.constoso.com" allowCredentials="true">
        <allowMethods>
            <add method="GET" />
            <add method="HEAD" />
            <add method="POST" />
            <add method="PUT" /> 
            <add method="DELETE" />         
        </allowMethods>
      </add>
    </cors>
  </system.webServer>
</configuration>

Redirect OPTIONS

You can redirect all OPTIONS requests to always give an OK status. This will however subvert the entire idea of a preflight request, so use this only if it's applicable to your situation.

Install the redirect module in IIS.
Add the following redirect to your Webconfig.

<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>

Middleware

Alternatively the desired result can be achieved by enabling anonymous authentication in IIS and creating a middleware in the Net Core API that checks if a person is properly authenticated.

Middleware:

public AuthorizationMiddleware(RequestDelegate next, ILogger logger)
{
    _next = next;
    _log = logger;
}

public async Task Invoke(HttpContext httpContext)
{
    //Allow OPTIONS requests to be anonymous
    if (httpContext.Request.Method != "OPTIONS" && !httpContext.User.Identity.IsAuthenticated)
    {
        httpContext.Response.StatusCode = 401;
        await httpContext.Response.WriteAsync("Not Authenticated");
    }
    await _next(httpContext);
}
like image 89
SanBen Avatar answered Oct 11 '22 18:10

SanBen