Piranha CMS - UseManager breaks CORS policy - .net-core

I am in the process of integrating Piranha CMS (v8.4) into an existing ASP .NET Core 3.1 project. I've gotten Piranha working, but I get an exception indicating CORS is not set up properly.
I've managed to track the source of the problem down to the configuration of the Piranha middleware. The line options.UseManager() is what causes the problem and when options.UseManager() line is commented out, the CORS middleware functions as expected.
app.UsePiranha(options =>
{
options.UseManager();
options.UseTinyMCE();
options.UseIdentity();
});
InvalidOperationException: Endpoint contains CORS metadata, but a middleware was not found that supports CORS. Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...).
My CORS policy is configured like this. Calling before or after UsePiranha makes no difference:
// global cors policy
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => env.IsDevelopment()) //any origin in dev
.AllowCredentials());
`

The problem is that the call to UseManager calls UseRouting. Per the exception, UseCors needs to be configured BEFORE UseRouting. The solution is to configure CORS between the calls to UseIdentity and UseManager.
app.UsePiranha(options =>
{
options.UseTinyMCE();
options.UseIdentity();
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => env.IsDevelopment()) //any origin in dev
.AllowCredentials());
options.UseManager();
});

Related

How to allow access to a NextJS api route from a different domain?

I have a NextJs with an /api/revalidate route for on-demand cache revalidation.
But I need to call this endpoint from a different domain and I'm getting the following error:
Access to XMLHttpRequest at 'DOMAIN_1/api/revalidate' from origin 'DOMAIN_2' 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.
How can I set up CORS on an API endpoint for a NextJS app?
Just found out that NextJS has an example about setting up CORS in an API route:
https://github.com/vercel/next.js/tree/canary/examples/api-routes-cors
And also you can use nextjs-cors, which is a wrapper on top of cors:
https://www.npmjs.com/package/nextjs-cors
The code will look something like this:
import NextCors from 'nextjs-cors';
async function handler(req, res) {
// Run the cors middleware
// nextjs-cors uses the cors package, so we invite you to check the documentation https://github.com/expressjs/cors
await NextCors(req, res, {
// Options
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
origin: '*',
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
});
// Rest of the API logic
res.json({ message: 'Hello NextJs Cors!' });
}

ServiceStatck gRPC

I had created a gRPC service using Servicestack and was able to consume from the console application.
When I a trying to call it from angular 12, i was getting the CORS issue I fixed by adding below code
services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-
Accept-Encoding", "Grpc-Web-Text");
}));
Now the CORS issue resolved However I am getting the below issue from angular
Grpc.AspNetCore.Server.ServerCallHandler[2]
Request content-type of 'application/grpc-web-text' is not supported.

Access to fetch has been blocked by CORS policy at Firebase Functions API

I'm working on my project which includes Angular 9 application using firebase functions. I deployed some function, which should update some values on the Firebase Realtime Database. Unfortunately, I encountered a problem with CORS policy if I use my API.
After adding middleware to my express server, where I added these code, the problem still occurs.
app.post('/changeQuantity', permit(), (request: any, response: any) => {
response.status(200).send({ data: { Message: 'Changing order quantity - success.' } });
})
export default function permit() {
return (req: any, _res: any, next: any) => {
_res.setHeader('Access-Control-Allow-Origin', '*');
_res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
next();
};
}
I noticed, that I get this error when frequently requesting API.
Here is the error which server returns:
Access to fetch at [here is a link to my API endpoint] from origin [my origin] 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Did anybody have the same issues with the firebase functions API? Could it be related to frequent requests of my API endpoints from the development environment? Thanks in advance.
Try using response.header to set the CORS properties, like this
app.use((request, response, next) => {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
next();
});

CORS error when making Axios calls to Cloudrun service from Firebase hosted app

This looks to be pretty obvious but I've been trying to figure it out for a couple of days now and still can't get it to work. Please, can someone point out what I'm missing.
I'm trying to make an axios call to my cloud run service from my firebase hosted SPA. To isolate the issue I followed the steps outlined in the [firebase tutorial for cloud run] (https://firebase.google.com/docs/hosting/cloud-run#node.js)
Step 4 of the tutorial talks about setting up rewrite to use the firebase domain as a proxy to your cloud run service. It says that the helloworld service would be reachable via
Your Firebase subdomains:
projectID.web.app/helloworld and projectID.firebaseapp.com/helloworld
So I follow the steps and deploy the service. Then I try to make an axios call to the service from the SPA like below
testHelloWorld () {
axios.get(`https://myProjectId.firebaseapp.com/helloworld`)
.then((data) => {
console.log(data)
})
.catch(ex => {
console.error(ex)
})
})
}
But then I get the CORS error
Access to XMLHttpRequest at 'https://myProjectId.firebaseapp.com/helloworld' from origin 'https://myFirabaseApp.firebaseapp.com' 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.
This answer states that this should be possible so I'm not sure what I'm doing wrong.
N.B:
While debugging, I updated the node app from the tutorial to add cors support like below. Still didnt work.
const express = require('express');
const app = express();
const cors = require('cors'); //Imported and added this
app.use(cors()); // Used here
app.get('/', (req, res) => {
console.log('Hello world received a request.');
const target = process.env.TARGET || 'World';
res.send(`Hello ${target}!`);
});
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log('Hello world listening on port', port);
});
So the question here is, how do I make an Axios/AJAX call to my cloud run service using the firebase rewrite rule?
Please check if you have installed cors: npm install cors.
Please check if the 2 following options can solve your issue:
1= Use the following code :
app.use(cors({origin:true,credentials: true}));
2) If the previous didn't work, please use the following code:
app.get('/', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
console.log('Hello world received a request.');
}
Please let me know if it works for you.

CORS header not being set for internal server error response ASP.NET Core 3.1

Here is my CORS configuration:
services.AddCors(options =>
{
options.AddPolicy(name: "AllowedOrigins",
policyBuilder =>
{
var urls = Configuration.GetSection("Host:AllowedOrigins").Get<List<string>>();
policyBuilder.WithOrigins(urls.ToArray())
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed((host) => true)
.AllowCredentials();
});
});
And in Configure method:
app.UseRouting();
app.UseCors("AllowedOrigins");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
For internal server error, there are no access-control-* headers in the response. As far as I know, this issue should be fixed since ASP.NET Core 2.2.
I created an issue for ASP.NET Core 3.1 and you can track the issue.
You need to explicitly call app.UseExceptionHandler(...) in your startup.
If you do not, then unhandled exceptions bubble up the call stack all the way to Kestrel. And Kestrel does not call the delegates hooked up to HttpContext.Response.OnStarting(...). CorsMiddleware (and many other middleware) use OnStarting to hook into adding information to the response.
Same problem in .Net 5 WebAPI project, so I guess it was not really solved by MS by the 2022..
The issue with the default behavior in my case, was that AXIOS (front-end library) does not provide any error response details unless CORS headers are present. Not sure if it's browser issue or the library issue but regardless the solution was to include CORS in response. This also got rid of the warning in console, which might have confused people, because despite warning - the status code is still 500 (it confused me also :) ).
Anyway, after following #TylerOhlsen 's answer, here what seems to have helped:
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
});
});
app.UseCors(...);
You might want to do something like:
if (!env.IsProduction())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
});
});
}
Some details about the UseExceptionHandler are here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0
For the practical explanation why this solution even works see the answer above/below. Thank you Tyler.

Resources