Compartilhamento de recursos entre origens (CORS)
O Compartilhamento de recursos entre origens (CORS) da Adobe Experience Manager as a Cloud Service facilita que propriedades da Web que não sejam de AEM façam chamadas do lado do cliente baseadas em navegador para APIs do GraphQL AEM do AEM e outros recursos Headless.
Requisito do CORS
O CORS é necessário para conexões baseadas em navegador com APIs do AEM GraphQL, quando o cliente que se conecta ao AEM AEM NÃO é atendido a partir da mesma origem (também conhecida como host ou domínio) que o.
Autor do AEM
A habilitação do CORS no serviço de autor do AEM é diferente dos serviços de visualização do AEM Publish e do AEM. O serviço de Autor do AEM requer que uma configuração OSGi seja adicionada à pasta modo de execução do serviço de Autor do AEM e não usa uma configuração do Dispatcher.
Configuração OSGi
A fábrica de configuração OSGi CORS do AEM define os critérios de permissão para aceitar solicitações HTTP CORS.
O exemplo abaixo define uma configuração OSGi para AEM Author (../config.author/..
), de modo que ela só esteja ativa no serviço AEM Author.
As principais propriedades de configuração são:
-
alloworigin
e/oualloworiginregexp
especifica a origem em que o cliente se conectando à Web AEM é executado. -
allowedpaths
especifica os padrões de caminho de URL permitidos nas origens especificadas.- Para dar suporte a consultas persistentes do AEM GraphQL, adicione o seguinte padrão:
/graphql/execute.json.*
- Para suportar Fragmentos de experiência, adicione o seguinte padrão:
/content/experience-fragments/.*
- Para dar suporte a consultas persistentes do AEM GraphQL, adicione o seguinte padrão:
-
supportedmethods
especifica os métodos HTTP permitidos para as solicitações CORS. Para dar suporte a consultas persistentes do GraphQL AEM (e Fragmentos de experiência), adicioneGET
. -
supportedheaders
inclui"Authorization"
, pois as solicitações ao Autor do AEM devem ser autorizadas. -
supportscredentials
está definido comotrue
, pois a solicitação ao Autor do AEM deve ser autorizada.
Saiba mais sobre a configuração OSGi do CORS.
O exemplo a seguir suporta o uso de consultas persistentes de AEM GraphQL no AEM Author. Para usar consultas GraphQL definidas pelo cliente, adicione uma URL de ponto de extremidade GraphQL em allowedpaths
e POST
a supportedmethods
.
/ui.config/src/main/content/jcr_root/apps/wknd-examples/osgiconfig/config.author/com.adobe.granite.cors.impl.CORSPolicyImpl~graphql.cfg.json
{
"alloworigin":[
"https://spa.external.com/"
],
"alloworiginregexp":[
],
"allowedpaths": [
"/graphql/execute.json.*",
"/content/experience-fragments/.*"
],
"supportedheaders": [
"Origin",
"Accept",
"X-Requested-With",
"Content-Type",
"Access-Control-Request-Method",
"Access-Control-Request-Headers",
"Authorization"
],
"supportedmethods":[
"GET",
"HEAD",
"POST"
],
"maxage:Integer": 1800,
"supportscredentials": true,
"exposedheaders":[ "" ]
}
Exemplo de configuração OSGi
Publicação no AEM
A habilitação do CORS nos serviços de AEM Publish (e Pré-visualização) é diferente do serviço de Autor do AEM. O serviço do AEM Publish requer que uma configuração do AEM Dispatcher seja adicionada à configuração do Dispatcher do AEM Publish. O AEM Publish não usa uma configuração OSGi.
Ao configurar o CORS no AEM Publish, verifique:
- O cabeçalho de solicitação HTTP
Origin
não pode ser enviado ao serviço AEM Publish, removendo o cabeçalhoOrigin
(se adicionado anteriormente) do arquivoclientheaders.any
do projeto AEM Dispatcher. Quaisquer cabeçalhosAccess-Control-
devem ser removidos do arquivoclientheaders.any
e gerenciados pelo Dispatcher, não pelo serviço AEM Publish. - Se você tiver alguma configuração OSGi do CORS habilitada em seu serviço AEM Publish, será necessário removê-la e migrar suas configurações para a configuração do Dispatcher vhost descrita abaixo.
Configuração do Dispatcher
O Dispatcher do serviço AEM Publish (e Pré-visualização) deve ser configurado para ser compatível com o CORS.
Definir cabeçalhos CORS no vhost
-
Abra o arquivo de configuração do vhost para o serviço AEM Publish, em seu projeto de configuração do Dispatcher, normalmente em
dispatcher/src/conf.d/available_vhosts/<example>.vhost
-
Copie o conteúdo do bloco
<IfDefine ENABLE_CORS>...</IfDefine>
abaixo para o arquivo de configuração do vhost habilitado.code language-none h-17 <VirtualHost *:80> ... <IfModule mod_headers.c> ################## Start of CORS configuration ################## SetEnvIfExpr "req_novary('Origin') == ''" CORSType=none CORSProcessing=false SetEnvIfExpr "req_novary('Origin') != ''" CORSType=cors CORSProcessing=true CORSTrusted=false SetEnvIfExpr "req_novary('Access-Control-Request-Method') == '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != ''" CORSType=invalidpreflight CORSProcessing=false SetEnvIfExpr "req_novary('Access-Control-Request-Method') != '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != ''" CORSType=preflight CORSProcessing=true CORSTrusted=false SetEnvIfExpr "req_novary('Origin') -strcmatch 'http://%{HTTP_HOST}*'" CORSType=samedomain CORSProcessing=false SetEnvIfExpr "req_novary('Origin') -strcmatch 'https://%{HTTP_HOST}*'" CORSType=samedomain CORSProcessing=false # For requests that require CORS processing, check if the Origin can be trusted SetEnvIfExpr "%{HTTP_HOST} =~ /(.*)/ " ParsedHost=$1 ################## Adapt regex to match CORS origin(s) for your environment SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.your-domain\.tld(d+?lang=pt-BR)?$)#" CORSTrusted=true # Extract the Origin header SetEnvIfNoCase ^Origin$ ^(.*)$ CORSTrustedOrigin=$1 # Flush If already set Header unset Access-Control-Allow-Origin Header unset Access-Control-Allow-Credentials # Trusted Header always set Access-Control-Allow-Credentials "true" "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Allow-Origin "%{CORSTrustedOrigin}e" "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Allow-Methods "GET" "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Max-Age 1800 "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Allow-Headers "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers" "expr=reqenv('CORSTrusted') == 'true'" # Non-CORS or Not Trusted Header unset Access-Control-Allow-Credentials "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" Header unset Access-Control-Allow-Origin "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" Header unset Access-Control-Allow-Methods "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" Header unset Access-Control-Max-Age "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" # Always vary on origin, even if its not there. Header merge Vary Origin # CORS - send 204 for CORS requests which are not trusted RewriteCond expr "reqenv('CORSProcessing') == 'true' && reqenv('CORSTrusted') == 'false'" RewriteRule "^(.*)" - [R=204,L] # Remove Origin before sending to AEM Publish if this configuration handles the CORS RequestHeader unset Origin "expr=reqenv('CORSTrusted') == 'true'" ################## End of CORS configuration ################## </IfModule> ... </VirtualHost>
-
Faça a correspondência das Origens desejadas que acessam seu serviço AEM Publish atualizando a expressão regular na linha abaixo. Se várias origens forem necessárias, duplique esta linha e atualize para cada origem/padrão de origem.
code language-none SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*.your-domain.tld(:\d+)?$)#" CORSTrusted=true
-
Por exemplo, para habilitar o acesso ao CORS a partir das origens:
- Qualquer subdomínio em
https://example.com
- Qualquer porta em
http://localhost
Substitua a linha pelas duas linhas a seguir:
code language-none SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.example\.com$)#" CORSTrusted=true SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(http://localhost(:\d+)?$)#" CORSTrusted=true
- Qualquer subdomínio em
-