I am trying to enable CORS on an ASP.NET Core MVC application. I am very frustrated.
I've already tried several snippets and none worked for me. This was my last attempt.
Startup.cs, "ConfigureServices" method.
services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader().AllowCredentials()));
Startup.cs, "Configure" method.
app.UseCors("AllowAll");
app.UseMvcWithDefaultRoute();
In my Controller I used this
[EnableCors("AllowAll")]
public class TestController : Controller
{
[Route("cors")]
public string Test()
{
return "Ok";
}
}
I am getting CORS issues on both Firefox and Chrome.
There is one important thing to know in order to make CORS work:
Access-Control-Allow-Origin
From the documentation at MSDN,
If the response doesn't include the Access-Control-Allow-Origin
header, the cross-origin request fails. Specifically, the browser
disallows the request. Even if the server returns a successful
response, the browser doesn't make the response available to the
client app.
If this header is present then generally your config should work.
You can verify this using fiddler.
There is one option to "Disable Same Origin" policy from the chrome and firefox. Please refer this blog for checking how to disable it.
But please note that this would make your browser vulnerable, this may be advisable to get it working during development, but not recommended at all for production scenarios.
Related
I'm having an issue with CORS in a .NET 6 Web API project. Development started in .NET 5, but was upgraded to .NET 6 later.
CORS was originally enabled using a named policy with AllowAnyHeaders() and AllowAnyMethods() as was explained in this Microsoft Docs article and this article on CodeMaze.
It worked perfectly fine on my local machine during development. However, when it was deployed to the testing server, only GET and POST works. PUT and DELETE do not work.
The PUT and DELETE requests in Postman for any PUT or DELETE method in any endpoint for any controller shows a 405 Method Not Allowed response. The Header's Allow field shows GET, HEAD, OPTIONS, TRACE.
However, changing PUT to OPTIONS still gives a 405 response, but the Allow field has DELETE, GET, PUT.
The Blazor WASM client shows the following in the console when attempting to edit or delete:
Access to fetch at 'http://ip-address:port/api/v1/EndpointName/92b956cd-2290-4270-8df5-056355cab846' from origin 'http://servername:port' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Since then I have read the MDN article explaining CORS and tried numerous solutions from various articles and Stack Overflow posts.
Origins work with .AllowAnyOrigins(), .WithOrigins("*"), and .WithOrigins(list hosts and ports).
Headers work with .AllowAnyHeader() and .WithHeaders("*"). Even after removing .WithExposedHeaders("X-Pagination") this header still shows and still works.
.AllowAnyMethod(), .WithMethods("PUT", "DELETE"), .WithMethods("*") all yield the same result described above.
The current code in the Startup.cs file is shown below:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
options.AddDefaultPolicy(
policy =>
{
policy.WithOrigins(Configuration["AllowedCORS"]);
policy.AllowAnyMethod();
policy.AllowAnyHeader();
policy.WithExposedHeaders("X-Pagination");
//policy.WithHeaders("*");
//policy.WithMethods("PUT", "DELETE");
//policy.WithMethods("*");
}));
services.AddControllers();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
...
}
Your assistance in resolving this issue is greatly appreciated.
According to my experience when the iis server does not allow delete and put while not having the same problem in dev machine, the problem is not related to CORS config and you should check two point to find the problem:
First ExtensionlessUrlHandler-Integrated-4.0 :
Go to Handler Mappings in your IIS Manager. Find ExtensionlessUrlHandler-Integrated-4.0, double click it. Click Request Restrictions... button and on Verbs tab, add both DELETE and PUT
Second WebDAVModule Should also allow the verbs: Check here
In my project, the negotiate, connect and start API calls all contain the required access-control-allow-origin header. However, as soon as SignalR calls the ping method, it throws the following error:
Access to XMLHttpRequest at 'https://backend.url/signalr/signalr/ping&_=1643292246714'
from origin 'https://frontend.url' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
I already modified my Startup.cs file according to Microsoft's documentation. I the old version, I was using the MapSignalR method instead.
public class Startup {
public void Configuration(IAppBuilder app) {
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR. By default this will allow all origins.
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR();
});
app.UseCors(CorsOptions.AllowAll);
}
}
However, this change didn't have any effect. The CORS error still persists. Any idea what's wrong here?
I'm using Microsoft.AspNet.SignalR 2.4.2 and Microsoft.Owin.Cors 4.2.0 with .NET Framework 4.8.
I also don't understand, why it's calling /signalr/signalr in the URL.
You should configure your CORS like (the order is important):
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder.WithOrigins(YourOriginsHere)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed((host) => true));
});
Note: Avoid putting * in the origins, it is better to create an array of strings with the possible origins, ideally reading it from configuration.
Update: For .NET Framework see how to enable CORS from this Microsoft documentation.
The actual problem was a bug in the client library I use. The solution was to update my client-side npm package signalr-asp-net. I still had version 1.0.0 and updated to 1.0.3. The problem is gone now.
I have a few web applications under the same domain, all using a stand alone Identity Server 3 app for login purposes. Under test environment, every single one of then are under the same domain (http://192.168.100.1, or by dns http://companyServer).
Recently, one application needed to request some data from another app, and I found the following error when debugging on Visual Studio:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://companyServer:60000/MyApp/Api/Company/Info?parameter=123. (Reason: CORS header 'Access-Control-Allow-Origin' not present).
We have a central library responsible for configuring Web API on our systems, it has the following (among other things):
public static IAppBuilder UseCebiUtilWebApi(this IAppBuilder app, CebiWebApiOptions options)
{
Logger.Debug("Configuring Web API");
app.UseCors(CorsOptions.AllowAll);
...
}
On the same method, we also configure Identity Server.
I also checked on my Login Server App, and there is the following code regarding CORS:
public class CompanyCorsPolicyService : DefaultCorsPolicyService
{
public CompanyCorsPolicyService()
{
base.AllowAll = true;
}
}
This method is being called on the project's Startup.cs.
As far as I know, every single end of my environmet should be enabling full CORS access, no matter the origin. But the header is still missing.
I've tried quite a few solutions on the internet:
Using "config.EnableCors" instead of "app.UseCors"
Overriding GrantResourceOwnerCredentials,
I have also tried setting up manually some CORS related headers on Web.Config, but I was unable to find the specific question here on SO.
I don't think identity server is related to this problem, but since that is the difference between my evironment and the solutions I've found, I decided to put it in here too.
Any ideas?
It's possible that the OPTIONSVerbHandler could be intercepting all OPTIONS (CORS pre-flight) requests.
Try disabling that so that ASP.Net can handle those requests instead.
So here is my Cors initialization code:
app.UseCors(builder =>
builder.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin());
And yet when I run PATCH I get the following error in Chrome 83:
Access to fetch at 'https://api-dev.myproject.com/api/mp' from origin 'https://users-dev.myproject.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Here is the code that is calling the api (from React):
const response = await fetch(API_URL() + `/mp`, {
method: 'PATCH',
body: `"${JSON.stringify(mpForm.values)}"`,
headers: {
Authorization: 'Bearer ' + apiToken,
'Content-type': 'application/json'
}
});
What could be going wrong here? Most API requests to this domain are just fine. It's just this one at the moment.
UPDATE
Just in case you are experiencing this exact issue, the root cause of this problem was the body line:
body: `"${JSON.stringify(mpForm.values)}"`,
and the issue was resolved by refactoring the API to work with a body like this instead:
body: JSON.stringify(mpForm.values),
The reason this was a problem was that the stringify function embedded double quotes in the return value, resulting in a string like this being passed:
'"{"foo":"bar"}"'
which then caused the CORS error.
Your CORS configuration looks correct, if some requests work, but not others then there is potential that the issue is not at the API end at all.
In the API startup.cs, make sure that CORS is configured before all other configurations.
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
This code is valid, though not very secure, it will satisfy browser CORS protocols globally for your app
Make sure that throughout your API there is no conflicting CORS config, look for individual CORS config on the controllers or methods for the request that is failing.
Check the client end, although your client code looks OK, the body is injected from a variable, to troubleshoot any client to server issues you need to either log the full request in plain text, or retrieve it from the network traffic inspection tools in your web browser at runtime.
If most queries to your API resolve correctly and it is only one or two that fail, this is a good indicator that there is a problem at the client end, you should probably start here.
Update:
OP's issue was not directly related to CORS at all, it is however a good reminder of two important lessons:
Malformed requests the Web API may fail before generating the correct response to an OPTIONS request, and if the OPTIONS request does not respond according to spec, the browser will report this as a CORS denial issue first, supressing the real erroneous response from the API
In posting issues to forums for advice on resolving errors, providing code that causes errors only paints part of the picture. You need to include logs that show the runtime values as well as the actual error message.
For debugging any Web API issues between client and server, you should always look at the actual HTTP Request and Response content and headers for the affected call, you can see the network trace using your browser dev tools, however if you need to regularly debug issues like this in production you should consider request trace logging either at the client or the server side.
You cannot combine 'allow any origin' with authorization. It's a security risk. Rather than allowing any origin, you can echo back the origin of the request, though you should be aware that doing is so brings some security risk - you're allowing auth tokens from any domain. It's better to configure CORS properly with the allowed domains.
Please see the accepted answer for this question: C# WEB API CORS does not work for one way to configure the backend in this scenario, avoiding the use of Access-Control-Allow-Origin:*.
After much troubleshooting, we were able to determine that the root cause of the issue was the body of the request. The stringify method was embedding double-quotes inside a string that was enclosed in double-quotes.
Why this caused a CORS error remains unclear to me, but it is likely a red herring.
Fixing the body resolved the issue.
I would be interested to understand the chain of events that led to a CORS error in the browser. But otherwise we have now resolved this.
I am trying to make an api call from a vue application to a .net core web api. Locally this works, when we then run it on our first dev environment we get this when it trys to make the request
Access to XMLHttpRequest at
'https://bla-api/api/foc?page=1&pageSize=10&sortBy=&sortDirection=ASC'
from origin 'https://bla-api' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I have added the following to the C#' Startup file in the ConfigureServices method. To just get it working I wanted to provide the *(wildcard), so let anyone call this. So presume that the named policy AllowAnyOrigin would do this!?
readonly string _SpecificOrigins = "AllowSpecificOrigins";
services.AddCors(options =>
{
options.AddPolicy(_SpecificOrigins,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
})
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
then also added this in the Configure method
app.UseCors(_SpecificOrigins);
app.UseMvc();
What am I missing? I also try and make a fiddler request to the api and it breaks.
Any help would be greatly appreciated
This was a red herring, the web api was not even deployed correctly, it was being deployued as a kestrel exe but was deployed as an azure web app. Adding a web.config pointing to the main api project resolved the issue. I did not write the deployment so that no needs looking at next. Presume the above question is fine then, cheers for the help