I am attempting to implement CORS in my web API layer of a project and limit the domains that the API will allow requests from. I am using the app.UseCors() method in my Startup.cs to setup CORS globally:
new public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
SystemConfiguration config = base.InitializeWebApiConfiguration();
// add our Cors Policy
app.UseCors(new CorsOptions
{
PolicyProvider = new CorsPolicyProvider
{
PolicyResolver = context => Task.FromResult(CorsPolicyHelper.GetCorsPolicy())
}
});
var authorizeAttribute = new AuthorizeAttribute();
config.HttpConfiguration.Filters.Add(authorizeAttribute);
app.UseNinjectMiddleware(() => this._kernel.Value);
app.UseNinjectWebApi(config.HttpConfiguration);
InitializeMappingProfiles();
}
The CorsPolicyHelper simply sets up a CorsPolicy object with the settings for Headers, Methods, Origins, etc. which are:
-AllowAnyMethod = true
-AllowAnyHeader = true
-SupportCredentials = true
-PreflightMaxAge = 604800 (7 days)
-Origins: "https://example.dev.com", "https://example-ci.test.com", "https://example-qa.test.com"
The problem I have is CORS is working on my dev and CI servers, however, it does not work on my QA server. My request has the correct origin "https://example-qa.test.com" but the resposne header does not include "Access-Control-Allow-Origin", and I am getting back:
XMLHttpRequest cannot load https://services-qa.test.com/api/data/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://example-qa.test.com' is therefore not allowed access. The response had HTTP status code 500.
I'm not sure what the difference is between my dev, CI, and QA servers are. They should be the same. But is it possible there is a server setting I need to change on my QA server to make it work? Possibly something in IIS?
Try this in your Web API's web.config (this version is cut down, but I'm sure you can put it together).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
So, it's working 2 out of 3. My understanding is that for a preflight request to be successful, your IIS site needs to be set to allow anonymous access. Check your IIS settings on all three boxes to verify.
It ended up being a different problem. The app.UseCors() method I described above does work to enable CORS globally. The problem was in a transform I had for my web.config for the QA environment. It was a problem with the connection to the server that gives me my identity token. Thanks for the suggestions though!
Related
We just had an external pen test and all of our sites are coming back with a low warning stating that we allow cross site scripting.
I don't think this is actually the case since we had to specifically allow it on one page on one specific site for that one to work.
The report shows that when calling our URL's a header for Access-Control-Allow-Origin is set to *.
Using Postman I can get that same result.
This is returning the same result from both ASP.Net web forms applications as well as new ASP.Net 6 Razor page apps.
Is there any way to have this header removed?
Maybe something in IIS?
To get rid of it you have to list all the origins that are allowed to send the requests to your endpoint. If you are running ASP.NET Core application then you have to configure the CORS middleware like this:
// Startup.ConfigureServices() method
// For example only, put these values in the appsettings.json so they could be overridden if you need it
var corsAllowAnyOrigin = false;
var corsAllowOrigins = new string[]{ "https://*.contoso.com", "https://api.contoso.com" };
// Configuring CORS module
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
if (apiConfiguration.CorsAllowAnyOrigin)
{
builder.AllowAnyOrigin();
}
else
{
builder.WithOrigins(apiConfiguration.CorsAllowOrigins);
}
builder.AllowAnyHeader();
builder.AllowAnyMethod();
});
});
For your Web Forms application you can install IIS CORS module and configure it in the web.config file like this:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<cors enabled="true">
<add origin="*" allowed="false"/>
<add origin="https://*.contoso.com" allowCredentials="false" />
<add origin="https://api.contoso.com" allowCredentials="true" />
</cors>
</system.webServer>
</configuration>
I have a WebApi done with .net core 3.1. It's hosted in the IIS in my laptop. At the same time I developed an angular UI and published it in the same IIS. Same IIS but each application has it's own port. When I insert a new record from the ui, it is done successfully, meaning the POST is successful. If I try to modify it, meaning a PUT, It does not go through. Seeing the developer tools in the browser, the console displays a message saying the Access to XMLHttpRequest at 'http://blablabla.com:777/api/items/333' from origin [the web application url goes here which is something like http://blablabla.com:778] has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have tried what I found in this website. Meaning that I modified the Startup.cs adding this in the ConfigureServices:
services.AddCors(options => {
options.AddPolicy(name: "Policy1", builder => {
builder.AllowAnyOrigin().AllowAnyMethod().WithHeaders(HeaderNames.ContentType, "Access-Control-Allow-Origin");
});
options.AddPolicy(name: "Policy2", builder => {
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
options.AddPolicy(name: "Policy3", builder => {
builder.WithOrigins("http://name.com:7771").AllowAnyHeader().AllowAnyMethod();
});
});
and this in the Configure method (after app.UseRouting();):
app.UseCors("Policy2");
I have no idea about what else to try.
After some time of full of frustration with this problem I finally found a solution.
Having this problem when trying to update (PUT). I can insert (POST) without any problem.
Access to XMLHttpRequest at 'http://superinspections.com:8000/api/Cities/12962'
from origin 'http://superinspections.com:8001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
Access to XMLHttpRequest at from origin has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Solution:
In IIS version 10:
click on the website you are having the access origin problem with (the back end) and double click on HTTP Reaponse Headers icon. Add the following entries:
Access-Control-Allow-Headers with valut *
Access-Control-Allow-Methods with value POST, PUT, GET, OPTIONS
Access-Control-Allow-Origin with value *
This will add the following to the web.config file of that site:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, GET, OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
After running the progran I did not have the Access-Control-Allow-Origin problem but I had a new message: HTTP 405 Method Not Allowed.
To solve this I found the solution here:
Web API Put Request generates an Http 405 Method Not Allowed error
And tha solution was to remove the WebDAV module with the following entry in the web config files in both, front end and back end.
Place this inside <system.webServer>.
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/> <!-- add this -->
</modules>
and add this to the handlers section:
<handlers>
<remove name="WebDAV" />
...
</handlers>
After that, the application was working as expected. I need to add that I needed to keep the cors configuration in the Startup.cs.
In the ConfigureServices:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod());
});
And in the configure, between app.UseRouting() and app.UseAuthentication()
app.UseCors("CorsPolicy");
and the attribute [EnableCors("CorsPolicy")] in the controllers that may need it.
For what I need, which is development and testing of an Angular application, this is sufficient. You may play with the Cors configuration in the client in order to get rid of the server setup, as I will do when I complete the development. But the WebDAV part I think that is unavoidable.
One thing I need to add is that the web config changes go away if you republish your back end.
Any comments will be appreciated. Specially an explanation of what is WebDAV.
I'm currently working on putting together my first React application, and I'm using fetch in order to communicate with my API which is currently being developed using the .net webapi. I am running into a bit of a wall however with getting my session variables on the .net server to work properly. Currently I'm running the react application separately locally and using the url of my .net server in order to make a request to the API server. Both of which are on the same machine despite using separate ports. The request is going through, but when i try to make a follow up request to get the current user information, it is not pull any information. I have looked, and it seems no cookies are being stored locally in the browser, so I'm assuming this is the issue. The code for my fetch looks something like this:
let url = "http://localhost:50405";
let requestObject = {
mode: 'cors',
credentials: 'include'
}
fetch(url + '/api/currentuser/get', requestObject).then((res) => {
console.log(res);
});
However, res is null even after the session has been set.
Also, on the server end, I have the following in my config file in order to allow for the cross-site request:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:3000" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
I figured I would see if there's something obvious I am missing here.
I'm using Angular and ASP.NET API. The issue I'm facing: when I add CORS in the API code, it works on Internet Explorer but does not work on Chrome and Firefox.
Here is the error:
XMLHttpRequest cannot load http://localhost:41028/api/values/abc. The
'Access-Control-Allow-Origin' header contains multiple values '*, *',
but only one is allowed. Origin 'http://localhost:44796' is therefore
not allowed access.
This is the code I added in the web.config file:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<!-- Adding the following custom HttpHeader will help prevent CORS errors -->
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
...
</system.webServer>
In the WebApiConfigFile.cs file I added:
var CorsAttribute = new EnableCorsAttribute("* ","* ", "* ");
config.EnableCors(CorsAttribute);
I'm using CORS for the first time. Any help will be appreciated.
You are setting CORS twice. I think that is the issue.
Please remove any one CORS settings. You can either remove it from web.config or from WebApiConfigFile.cs.
Chrome and Firefox use what is called a pre-flight check using the "OPTIONS" verb.
So, you have to add "OPTIONS" to the allowed methods in the web.config. You also may have to add some code to the Application_Begin request, like this answer suggests:
Handling CORS Preflight requests to ASP.NET MVC actions
Here are some resources for CORS:
IIS hijacks CORS Preflight OPTIONS request
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
All other solutions provided for webAPI. This solution is for when you using webservice(.asmx) as API
Remove 'Access-Control-Allow-Origin' details from either in Global.asax.cs file's begin_request function or in web.config. Because this setting must be in one place only
I got this issue because I put the app.UseCors after ConfigureOAuth. Change the order fix the problem.
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureOAuth(app);
WebApiConfig.Register(config);
// Used to put this line after ConfigureAuth(app),
// app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
Here is the detail in my case:
At the beginning I got Origin is not allowed in 'Access-Control-Allow-Origin', when calling \token.
LSo I add the customHeader including 'Access-Control-Allow-Origin', 'Access-Control-Allow-headers', 'Access-Control-Allow-methods'. It fixed the \token request.
But then I got duplicate 'Access-Control-Allow-Origin' when calling detail api. There are a lot suggestions, such as this just couldn't fix.
I had the same issue. After I put the exact domain instead of * (see below), it worked for me.
var CorsAttribute = new EnableCorsAttribute("https://www.mywebsite.com","", "");
config.EnableCors(CorsAttribute);
I had the exact same error and the reason was that
"Access-Control-Allow-Origin: *"
header was already present in the IIS HTTP Response Headers list.
Example
Removing it from the list worked for me.
I am either getting a 400, 404, or 405 error attempting to query my Web API OData Service.
My remote service name is configured to:
var remoteServiceName = 'http://localhost:50056/odata/';
In my entityManagerFactory I have Odata set:
breeze.config.initializeAdapterInstance('dataService', 'webApiOData', true);
And in my datacontext I am calling:
var manager = entityManagerFactory.newManager();
return breeze.EntityQuery.from('Courses')
.using(manager).execute()
.then(success).catch(failed);
I am currently getting the error:
XMLHttpRequest cannot load http://localhost:50056/odata/$metadata. No 'Access-Control-Allow-Origin' header is present on the requested resource
I can access this path just fine in the browser. I've found several resources to suggest I need to set the httpProtocol in my web.config as follows:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
</customHeaders>
</httpProtocol>
But that just gives me a
XMLHttpRequest cannot load http://localhost:50056/odata/$metadata. The 'Access-Control-Allow-Origin' header contains multiple values
I have also tried to set these settings from IIS Express's applicationhost config file but that gives me the following:
Invalid HTTP status code 400
I have also heard that adding the following setting to WebApiConfig should work:
config.EnableCors();
But I see no effect, and alternatively I have tried:
var cors = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*");
config.EnableCors(cors);
Which also has no effect. I don't see what else I could be missing as I've exhausted every resource I've found online.
I am using Visual Studio 2013 express and using IIS express.
I found my problem. I was using OData v4. Apparently datajs does not support OData v4 yet. Adding the following code in the WebApiConfig smoothed things out even further:
var cors = new EnableCorsAttribute("*", "*", "*", "DataServiceVersion, MaxDataServiceVersion");
config.EnableCors(cors);
Ahh. At the moment the Web Api implementation of OData is full of pot holes ... including but not limited to lagging data.js support.
I'm in touch with the OData team and hopeful we can make progress soon.
Do you really need OData? Unless you need to support open clients, it is much better to go straight Web Api.