.NET Sessions with React Cross Origin - asp.net

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.

Related

Disable Access-Control-Allow-Origin in ASP.Net and ASP.Net Core

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>

Deleting media using the WordPress REST API

I'm trying to delete media from the WordPress Library using the rest-api with cookie authentication. I can create a file (POST) and retrieve (GET) the file contents, but DELETE do not work. I'm using IIS Version 10.0.
Note: this code is ran on the website domain, not from another domain.
Things I've tried:
Enabling WebDAV on the server
Used Basic WordPress authentication plugin
Here is the XMLHttpRequest that I'm using:
var apiCall = new XMLHttpRequest();
apiCall.onreadystatechange = function() {
...
};
apiCall.open("DELETE", wpApiSettings.root + "wp/v2/media/");
apiCall.setRequestHeader("X-WP-Nonce", wpApiSettings.nonce);
apiCall.send("2000");
The error I get back:
HTTP Error 401.0 - Unauthorized. You do not have permission to view this directory or page.
This error is never present with GET or POST, only when doing the delete, which makes me think about the authentication within IIS. Maybe it's not even reaching the WordPress engine and IIS is intercepting the request and denying it. Which I thought enabling WebDAV would fix, but sadly, it did not.
First, 401 error typically indicates the request is not authenticated. We have to set up the credential based on the authentication mode in IIS. If it requires basic credential, we need to set up the HTTP header like below,
xhr.setRequestHeader('Authorization', 'Basic ZWx1c3VhcmlvOnlsYWNsYXZl');
How to send a correct authorization header for basic authentication
In addition, for supporting Delete HTTP verb, please add the below code to your the webconfig file.
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/> <!-- ADD THIS -->
</modules>
Here is a related discussion.
WebAPI Delete not working - 405 Method Not Allowed

Sending JSON between localhost ports

I had an ASP.NET MVC app running on port 8799 that posted JSON data via an XMLHttpRequest to an MVC controller handler. This pipeline was working perfectly fine.
I recently spun up a second app, this time an Express app running on port 8080, that again posts JSON in the same way (same exact code, using again an XMLHttpRequest), to the same MVC controller running on port 8799. This time, however, it appears as though while the request is received by the controller, there is no data on it.
I'm wondering if this is because I am making a cross-origin request between these two ports. Going off of this hypothesis, I added the following custom headers to my web.config file:
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost" />
<add name="Access-Control-Allow-Headers" value="X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
<add name="Access-Control-Max-Age" value="1000" />
</customHeaders>
This does not seem to solve the issue. How can I debug this problem, I don't seem to be throwing any particularly useful exceptions?
The issue did turn out to be CORS. For whatever reason the web.config file was not being used by my .NET application. Thus, I setup CORS setting in my Startup.cs file instead, using services.AddCors() in my Configure() call.

CORS Server Settings for ASP.net?

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!

Breezejs Web api OData method not allowed

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.

Resources