Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS does not work with CDN #3520

Closed
ackava opened this issue Sep 7, 2018 · 17 comments
Closed

CORS does not work with CDN #3520

ackava opened this issue Sep 7, 2018 · 17 comments
Assignees
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates investigate

Comments

@ackava
Copy link

ackava commented Sep 7, 2018

It is quite well that ASP.NET Core detects whether CORS headers are needed or not, but it does not work with CDN. In requests through CDN, ASP.NET Core thinks that it does not need to send CORS headers and it simply stops sending CORS headers.

@Eilon
Copy link
Member

Eilon commented Sep 10, 2018

@ackava can you provide more info on how things are set up, and what exactly doesn't work? Usually it's the CDN that needs CORS headers set up.

@blowdart
Copy link
Contributor

And generally CDNs don't require CORS, because, well, they're open to multiple sites, so listing each one would be a nightmare.

@Eilon
Copy link
Member

Eilon commented Sep 10, 2018

@blowdart they do need CORS so that JS files can programmatically download files from them, such as fonts. But, their CORS settings would probably be to blanket-allow all hosts for all things.

@blowdart
Copy link
Contributor

Ah yea, ok, I poorly worded :) Allowing all is basically "I don't have requirements" to my mind.

@ackava
Copy link
Author

ackava commented Sep 10, 2018

@Eilon Here is what I have,

I have JS module resolver that downloads JS modules (individual files) via XHR and executes in either eval or script inject (RequireJS, SystemJS) all of them do exactly same thing.

CDN through Azure CDN, does not send CORS headers, where else cdn.jsdelivr.net etc they do. Unfortunately, CORS headers detects that there is no need to send CORS and it does not send any CORS headers. I don't want to setup CORS on CDN because it is an additional configuration overhead outside of application. I have many tenants on the system and thus everyone have their own CDN pointing to root application.

There should be a simple way to force sending headers even if they are not required.

My work around now is to remove default CORS config and I have to write a module to force CORS headers.

        app.Use(async (context, next) => {

                if( isJavaScriptResource(context)) {
                    IHeaderDictionary headers = context.Response.Headers;
                    headers.Add("access-control-allow-origin", "*");
                    headers.Add("access-control-expose-headers", "*");
                    headers.Add("access-control-allow-methods", "*");
                    headers.Add("access-control-allow-headers", "*");
                    headers.Add("access-control-max-age", "300");
                }
                await next();

       });

@Eilon
Copy link
Member

Eilon commented Sep 10, 2018

You set up your own Azure CDN instance?

But either way I think I'm missing something here: if you're using an Azure CDN, how does setting the response headers of your web app have any effect on this at all?

@Eilon
Copy link
Member

Eilon commented Sep 10, 2018

That is, CORS is between the web browser and the CDN, not your web app.

@ackava
Copy link
Author

ackava commented Sep 10, 2018

Azure CDN has custom origin set to my appilcation. So CDN simply forwards headers if they are present in the response. Otherwise CDN does not send CORS headers.

My app is,

https://secure.app.com

and CDN url is

https://myapp.edgecdn.net

All JavaScripts referenced in page are loaded from CDN url and not my app url.

When JavaScript is loaded from different domain, Chrome does not allow AJAX requests as chrome maintains source as CDN and does not allow any AJAX request to app url. If JavaScript response has allow origin * then there is no issue with AJAX.

@Eilon
Copy link
Member

Eilon commented Sep 10, 2018

Ah, I see now how this is configured, thank you for explaining. The Azure CDN essentially proxies requests back to your own app (if needed).

When it wasn't working initially, how were you setting CORS? ASP.NET Core doesn't send any CORS headers by default - you have to use either the CORS middleware or MVC's CORS features.

@ackava
Copy link
Author

ackava commented Sep 11, 2018

I did use MVC's CORS feature, but it does not work.

Here is what I tried,

        services.AddCors(options =>
        {
            options.AddPolicy("UIProxy", builder =>
                builder
                    .AllowAnyMethod()
                    .AllowAnyOrigin()
                    .WithHeaders("Content-Type", "Cache-Control")
                    .SetPreflightMaxAge(TimeSpan.FromDays(1))
            );
        });

And ...

   [Route("ui")]
   [EnableCors("UIProxy")]
   public class UIController: Controller {
   } 

OR

   // enabled CORS globally for every request
   app.UseCors("UIProxy");

None of them worked !!

@Eilon
Copy link
Member

Eilon commented Sep 11, 2018

The MVC CORS feature applies only to requests that come in to MVC itself. Because in your case these are presumably all requests for static files, chances are that the Static Files middleware will handle them all.

So, that brings us to .UseCors(), which you'd need to make sure runs before calling .UseStaticFiles(), so that the CORS middleware will run before the Static Files middleware, so that it has a chance to add the headers you want.

Can you confirm you had the middleware in that order?

@pranavkm
Copy link
Contributor

@ackava have you had a look at the logs? The CORS middleware does not send headers if it calculates that the policy does not match.

@ackava
Copy link
Author

ackava commented Sep 11, 2018 via email

@mkArtakMSFT
Copy link
Member

@pranavkm, can you please investigate this further? If there is a specific configuration required for this scenario, we should just document it.,

@mkArtakMSFT mkArtakMSFT added this to the 2.2.0 milestone Oct 8, 2018
@mkArtakMSFT mkArtakMSFT modified the milestones: 2.2.0, 3.0.0 Nov 1, 2018
@pranavkm
Copy link
Contributor

pranavkm commented Nov 6, 2018

I just feel that CORS should have ability to send headers without checking input request.

The values for Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Method` are calculated by the middleware based on the incoming request. For most parts, the middleware would not be able to send meaningful header responses for non-CORS requests.

I am not using UseStaticFiles

The CorsMiddleware logs it's evaluation for every incoming request and why it decided not to send a CORS response. That would help here.

@ackava
Copy link
Author

ackava commented Nov 6, 2018

@pranavkm My request here is simple, irrespective of incoming request headers, I should be able to simply force Access-Control headers. A simple config to override all calculation and send header will suffice.

@mkArtakMSFT
Copy link
Member

@ackava, this is not something we plan to do:

irrespective of incoming request headers, I should be able to simply force Access-Control headers. A simple config to override all calculation and send header will suffice.

You can achieve what you want by simply registering a custom middleware to write any headers you want.

@Eilon Eilon added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates and removed repo:CORS labels Nov 26, 2018
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates investigate
Projects
None yet
Development

No branches or pull requests

5 participants