Reputation: 3298
In my asp.net core web api, I've configured Cors as per the article from MS documentation. The web api app is using windows authentication (Anonymous Authentication is Not enabled). Cor's policy is created and middle ware is added as below in the startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddMvc().AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//Enable CORS policy
app.UseCors("CorsPolicy");
app.UseMvc();
}
Also applied the policy per controller level
[EnableCors("CorsPolicy"), Route("api/[controller]")]
public class LocationController : BaseController<Location>
{
//code
}
Options request is getting Unauthorized. The request & response looks like
I have seen similar questions and tried almost every solution but the options request is still failing.
Upvotes: 19
Views: 15905
Reputation: 29
Just a note CORS middleware doesn't work in IIS see this thread here
web.release.config
on the root of your app<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web xdt:Transform="Insert">
<authentication mode="Windows"/>
</system.web>
<system.webServer xdt:Transform="Insert">
<cors enabled="true" failUnlistedOrigins="true" >
<add origin="your origin" allowCredentials="true" >
<allowHeaders allowAllRequestedHeaders="true">
<add header="your header" />
</allowHeaders>
</add>
</cors>
</system.webServer>
</configuration>
Upvotes: 0
Reputation: 111
1) Set Allow Windows, and anonymous Authentication flag to true in launchSettings.json file (Development settings file).
Anonymous Authentication: is needed to allow Pre flight option request.
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iis":
...
}
2) Add Cors Policy in Configure service method.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddCors(options =>
{
options.AddPolicy("MyCustomCorsPolicyName",
builder => builder.WithOrigins("http://YourDomainName/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
3: Adds a CORS middleware to your web application pipeline to allow cross domain requests.
public void Configure(IApplicationBuilder app)
{
....
app.UseCors("MyCustomCorsPolicyName");
app.UseMvc();
}
4) Add Authorize Attribute on top of your controller to Force, client to send credentials
[Authorize]
public class MyAPIController : ControllerBase
{
...
}
5) In JQuery or any client that you are using set withCredentials property flag to true
$.ajax({
type: "POST",
datatype: "json",
url: "YourApiUrl",
xhrFields: {
withCredentials: true
}
This worked for me in my development environment using .net core 2.2, IIS Express with Windows Authentication.
Upvotes: 10
Reputation: 268
After a couple hours figuring it out, here is a COMPLETE solution (front-end to back-end):
My problem: When I enabled the windows authentication on my web API, I could not do fetch calls from my react app to my .NET Core 3.1 web API, CORS was freaking out. With Anonymous authentication it worked, but not when windows authentication is enabled.
1.launchSettings.json
this will be used only for your dev environnment, make sure windows auth is also enabled in IIS on your prod server.
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:58747",
"sslPort": 0
}
},
{... more settings if any}
}
2.Startup.cs:
CORS policy is enabled here. The order of methods is important here. Also, you don't need to set those in a web.config
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", //give it the name you want
builder =>
{
builder.WithOrigins( "http://localhost:3000", //dev site
"production web site"
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
//database services here
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// global policy same name as in the ConfigureServices()
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
3.Controller(s):
using Microsoft.AspNetCore.Cors;
... your other usings
namespace ProjectTest.Controllers
{
[ApiController]
[EnableCors("CorsPolicy")] //THIS HERE needs to be the same name as set in your startup.cs
[Route("[controller]")]
public class FooController:Controller
{
[HttpGet("getTest")]
public JsonResult GetTest()
{
return Json("bar");
}
}
}
4.React Component fetch call example:
The "credential: 'include'" is the secret
await fetch('http://localhost:3000/Foo/getTest', {
method: 'GET',
credentials: 'include'
}).then(resp => resp.json());
Upvotes: 0
Reputation: 31
Using IIS CORS Module solved the problem superbly. Below URL is for reference.
Working with Windows Authentication While this is by no means the only scenario solved by the CORS module, it was important enough to warrant calling out. Previously, if you tried to make a cross-domain request to an application that used Windows Authentication, your preflight request would fail since the browser did not send credentials with the preflight request. There was no way to work around this without enabling anonymous authentication in your application. Since the CORS module kicks in before authentication, it makes it possible to handle a pre-flight request without compromising on the security model of your application. Here's an example of what your web.config might look like.
https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
Sample Code:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- To customize the asp.net core module uncomment and edit the following section.
For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
<system.web>
<authentication mode="Windows"/>
</system.web>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="http://localhost:60096" allowCredentials="true" >
<allowHeaders allowAllRequestedHeaders="true">
<add header="Header1" />
</allowHeaders>
</add>
</cors>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Project.Api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
Upvotes: 1
Reputation: 61
It looks like you want pass credential or along with request.
Please Check this link for add credential / allow user credential.
Be careful when allowing cross-origin credentials. A website at another domain can send a logged-in user's credentials to the app on the user's behalf without the user's knowledge. The CORS specification also states that setting origins to "*" (all origins) is invalid if the Access-Control-Allow-Credentials header is present.
Upvotes: 0
Reputation: 181
This is very similar to CORS enabled but response for preflight has invalid HTTP status code 404 when POSTing JSON and provided solution working for me(I had 401 error on POST requests). Also NTLM and Negotiate should not be configured both(Negotiate V/s NTLM).
Upvotes: 0
Reputation: 2909
You may want to read this thread: https://github.com/aspnet/CORS/issues/60. You can mix anonymous and NTLM so that your CORS preflights aren't denied (since they don't include windows credentials). IIS handles NTLM authentication before it even gets to the middleware so this is probably an IIS thing. You may need to allow anonymous CORs preflight checks.
Upvotes: 10