Expand my Community achievements bar.

Dispatcher CORS configuration - gap in documentation

Avatar

Level 4

Hi,

I've just worked through configuring our AEM dispatchers to support CORS requests and I think the Adobe documentation needs improvement.  Configuring a CORS policy via system/console was straightforward enough but while direct requests to our publish instances returned a valid response (with expected "Access-Control-Allow-Origin:..." in the response headers) requests via our dispatchers did not (and no CORS request handling was being logged in our publisher's output).

I couldn't understand the issue: it turned out additional dispatcher cache/headers are required but supporting​ info explaining this is unintuitive​.  I'd seen the documentation but didn't think I was at the point of worrying about caching - since i didn't yet have a valid response to cache.

Fortunately I stumbled upon this KB video - Adobe Experience Manager Help | Developing for Cross-Origin Resource Sharing (CORS) with AEM  - where the presenter says "...we add the CORS headers to the dispatcher config to allow our CORS headers to be passed through as well as cached...".  Eureka!

Could the documentation be improved to make this more obvious and a more explicit CORS dispatcher configuration section be used for this setting?

10 Replies

Avatar

Level 10

We will log a DOC Bug based on this thread!

Avatar

Level 4

Hi thanks @smacdonald2008.

Actually this is proving more problematic than we first thought - some advice and further info from Adobe would be appreciated.

So far, I've only been able to get CORS request handling to work via the dispatcher if we add appropriate 'header' entries to the 'cache' section of the dispatcher config.  So whether we want to or not, we end up caching CORS response headers.  The problem is that in our use case we have an osgi CORS policy regex that allows a number of origins but because of the CORS response caching only the first requester will succeed until cache expiry (subsequent CORS requests from other origins fail since the cached origin is different to the current requester's origin (even though they are an 'allowed origin' under our policy)).

It is font files under etc/designs that are the allowed content and therefore good candidates for caching.

How can we solve this ? 

Avatar

Level 2

I am facing the exact same issue. There is a css that is used by multiple domains and CORS policy is requires on font files. Works when serving the font file from publisher but not after it gets cached on dispatcher.

Followed the same docs advising to add origin header cache on the dispatcher.

Rather useless because it will only cache the first origin header and causes all other subsequent origins to be blocked.

Is this a limitation of the dispatcher?

Avatar

Level 4

any update on this ? We are facing issues when trying for multiple domains. It is only working for first entry.

Avatar

Level 2

I think the best solution is to handle "Multi-Domain-CORS" for AEM - outside of AEM and dispatcher. Do NOT use AEMs OSGi Config for "Adobe Granite Cross-Origin Resource Sharing Policy OSGi", and do not touch the Dispatcher config.

You can handle the CORS security on the Apache level alone (somewhat like SSL termination - handle this on the first device in your control).

By my understanding step 1. is also not required, and can actually negatively influence the CORS functionality.

My testing showed that AEM already blocked the request if the request came from a "wrong" domain, and the dispatcher also made some problems when the CORS-OSGi config was configured.

I think it is best to NOT configure AEM, you do not need to configure the dispatcher (to passthrough headers), and only configure the Apache to add the following code to the Apache configuration/vHost, and to adjust the reg-ex to hold all your "origin"-domains and sub-domains:

<IfModule mod_headers.c>

    SetEnvIfNoCase Origin "https?://(www\.)?(domain1\.com|domain2\.com)(:\d+)?$" ACAO=$0

    Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO

    Header set Vary Origin

</IfModule>

I think it is also a good idea to add/merge the VARY-header as "Vary: Origin" to tell an upstream CDN the signal, that separate copies of the responses (content&Header) should be stored in the CDN, depending on the requesting Origin.

Avatar

Level 4

Thanks Robert. This was the exact solution that worked for us as well. Forgot to update forum.

Avatar

Level 4

smacdonald2008​ can Adobe help with any further info about my follow up point around CORS header caching?

Are there any other ways to address the problem that the first requesting origin is the one that gets written into the header cache (meaning subsequent requests from other authorised origins are blocked)?

Would having individual CORS policies for each allowed origin help - or would the caching problem still be there?  Are there other ways to configure the apache dispatcher to allow CORS response headers through - e.g. using the dispatcher clientheaders section?

Avatar

Level 2

Hi DorianHallward, I got it to work by adding this config to apache. Basically, if the request has origin from any of your whitelist domains, it will rewrite the header on the spot to allow that origin. The domain regex should match what you have in com.adobe.granite.cors.impl.CORSPolicyImpl.xml.

<IfModule mod_headers.c>

  SetEnvIfNoCase Origin "https?://.*\.(origin1.com|origin2.com|origin3.com)$" ACAO=$0

  Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO

</IfModule>

Avatar

Level 4

Thanks jonnow

so has your solution been to,

1. set osgi CORS policy

2. configure your apache/dispatcher cache section to enable CORS header pass through and cache CORS response headers in dispatcher

3. configure mod_headers in apache to overwrite any Access-Control-Allow-Origin response headers cached by the dispatcher and replace that header value with the matching entry from your whitelist?

If i've understood how it works that sounds great and i will give it a try.

Still feels like the aem/dispatcher implementation for cors support is broken! 

Avatar

Level 2

Hey pretty much, except you don't need step 2.

Caching the headers does nothing here.