Entenda o compartilhamento de recursos entre origens (CORS)
O compartilhamento de recursos entre origens (CORS) do Adobe Experience Manager ajuda propriedades da web que não são do AEM a fazerem chamadas do lado do cliente para o AEM, tanto autenticadas quanto não autenticadas, para obter conteúdo ou interagir diretamente com o AEM.
A configuração de OSGI descrita neste documento é suficiente para:
- Compartilhamento de recursos de origem única no AEM Publish
- Acesso do CORS ao AEM Author
Se o acesso do CORS de várias origens for necessário no AEM Publish, consulte esta documentação.
Configuração de OSGi da política de compartilhamento de recursos entre origens do Adobe Granite
As configurações do CORS são gerenciadas como fábricas de configuração de OSGi no AEM, sendo que cada política é representada como uma instância da fábrica.
http://<host>:<port>/system/console/configMgr > Adobe Granite Cross Origin Resource Sharing Policy
Adobe Granite Cross-Origin Resource Sharing Policy (com.adobe.granite.cors.impl.CORSPolicyImpl
)
Seleção de política
Uma política é selecionada, comparando-se o
Allowed Origin
com o cabeçalho da solicitaçãoOrigin
- e
Allowed Paths
com o caminho da solicitação.
A primeira política correspondente a esses valores é usada. Se nenhuma for encontrada, qualquer solicitação CORS será negada.
Se nenhuma política for configurada, as solicitações CORS também não serão respondidas, pois o tratador estará desabilitado e, portanto, será efetivamente negado, desde que nenhum outro módulo do servidor responda a CORS.
Propriedades da política
Origens permitidas
"alloworigin" <origin> | *
- Lista de parâmetros
origin
, especificando URIs que podem acessar o recurso. Para solicitações sem credenciais, o servidor pode especificar * como curinga, permitindo que qualquer origem acesse o recurso. Não é recomendável usarAllow-Origin: *
na produção, pois isso permite que qualquer site externo (ou seja, invasor) faça solicitações que, sem o CORS, são estritamente proibidas pelos navegadores.
Origens permitidas (Regexp)
"alloworiginregexp" <regexp>
- Lista de expressões regulares
regexp
, especificando URIs que podem acessar o recurso. As expressões regulares podem levar a correspondências não intencionais, se não forem criadas com cuidado, permitindo que um invasor use um nome de domínio personalizado que também corresponda à política. Em geral, é recomendável contar com políticas separadas para cada nome de host de origem específico, usando-sealloworigin
, mesmo que isso signifique a configuração repetida das outras propriedades da política. Diferentes origens tendem a ter diferentes ciclos de vida e requisitos, beneficiando-se, assim, de uma separação clara.
Caminhos permitidos
"allowedpaths" <regexp>
- Lista de expressões regulares
regexp
, especificando caminhos de recursos aos quais a política se aplica.
Cabeçalhos expostos
"exposedheaders" <header>
- Lista de parâmetros de cabeçalho que indica os cabeçalhos de resposta que os navegadores têm permissão para acessar. Para solicitações de CORS (não simuladas), se não estiverem em branco, estes valores serão copiados no cabeçalho de resposta
Access-Control-Expose-Headers
. Então, os valores na lista (nomes de cabeçalho) ficam acessíveis ao navegador. Sem eles, esses cabeçalhos não são legíveis pelo navegador.
Idade máxima
"maxage" <seconds>
- Um parâmetro
seconds
que indica por quanto tempo os resultados de uma solicitação simulada podem ser armazenados em cache.
Cabeçalhos aceitos
"supportedheaders" <header>
- Lista de parâmetros
header
, indicando quais cabeçalhos de solicitação HTTP podem ser usados ao fazer a solicitação real.
Métodos permitidos
"supportedmethods"
- Lista de parâmetros de método que indica quais métodos HTTP podem ser usados ao fazer a solicitação real.
Permite credenciais
"supportscredentials" <boolean>
- Um
boolean
, indicando se a resposta à solicitação pode ou não ser exposta ao navegador. Quando usado como parte de uma resposta a uma solicitação simulada, indica se a solicitação real pode ou não ser feita por meio de credenciais.
Exemplos de configurações
O site 1 é um caso básico, acessível anonimamente e somente de leitura, no qual o conteúdo é consumido por meio de solicitações GET:
{
"supportscredentials":false,
"exposedheaders":[
""
],
"supportedmethods":[
"GET",
"HEAD"
],
"alloworigin":[
"http://127.0.0.1:3000",
"https://site1.com"
],
"maxage:Integer": 1800,
"alloworiginregexp":[
"http://localhost:.*"
"https://.*\.site1\.com"
],
"allowedpaths":[
"/content/_cq_graphql/site1/endpoint.json",
"/graphql/execute.json.*",
"/content/site1/.*"
],
"supportedheaders":[
"Origin",
"Accept",
"X-Requested-With",
"Content-Type",
"Access-Control-Request-Method",
"Access-Control-Request-Headers"
]
}
O site 2 é mais complexo e requer solicitações autorizadas e mutantes (POST, PUT, DELETE):
{
"supportscredentials":true,
"exposedheaders":[
""
],
"supportedmethods":[
"GET",
"HEAD"
"POST",
"DELETE",
"PUT"
],
"alloworigin":[
"http://127.0.0.1:3000",
"https://site2.com"
],
"maxage:Integer": 1800,
"alloworiginregexp":[
"http://localhost:.*"
"https://.*\.site2\.com"
],
"allowedpaths":[
"/content/site2/.*",
"/libs/granite/csrf/token.json",
],
"supportedheaders":[
"Origin",
"Accept",
"X-Requested-With",
"Content-Type",
"Access-Control-Request-Method",
"Access-Control-Request-Headers",
"Authorization",
"CSRF-Token"
]
}
Receios e configuração do armazenamento em cache do Dispatcher dispatcher-caching-concerns-and-configuration
A partir do Dispatcher 4.1.1+, os cabeçalhos de resposta podem ser armazenados em cache. Isso permite o armazenamento em cache de cabeçalhos CORS junto com os recursos solicitados por CORS, desde que a solicitação seja anônima.
Geralmente, as mesmas considerações para armazenamento em cache do conteúdo no Dispatcher podem ser aplicadas ao armazenamento em cache de cabeçalhos de resposta do CORS no Dispatcher. A tabela a seguir define quando cabeçalhos de CORS (e, portanto, solicitações CORS) podem ser armazenados em cache.
Permitir cabeçalhos de solicitação do CORS
Para permitir que os cabeçalhos de solicitação HTTP necessários sejam transmitidos para o AEM para processamento, eles precisam ser permitidos na configuração /clientheaders
do Dispatcher.
/clientheaders {
...
"Origin"
"Access-Control-Request-Method"
"Access-Control-Request-Headers"
}
Armazenamento em cache de cabeçalhos de resposta do CORS
Para permitir o armazenamento em cache e a veiculação de cabeçalhos do CORS no conteúdo em cache, adicione a configuração /cache /headers ao arquivo dispatcher.any
do AEM Publish.
/publishfarm {
...
/cache {
...
# CORS HTTP response headers
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#the_http_response_headers
/headers {
...
"Access-Control-Allow-Origin"
"Access-Control-Expose-Headers"
"Access-Control-Max-Age"
"Access-Control-Allow-Credentials"
"Access-Control-Allow-Methods"
"Access-Control-Allow-Headers"
}
...
}
...
}
Lembre-se de reiniciar o aplicativo do servidor da web depois de fazer alterações no arquivo dispatcher.any
.
Provavelmente, será necessário limpar todo o cache para garantir que os cabeçalhos sejam armazenados em cache de maneira adequada na próxima solicitação após uma atualização da configuração /cache/headers
.
Resolução de problemas do CORS
O registro em log está disponível no com.adobe.granite.cors
:
- habilite
DEBUG
para ver mais detalhes sobre o motivo de uma solicitação CORS ter sido negada - habilite
TRACE
para ver mais detalhes sobre todas as solicitações que passam pelo tratador de CORS
Dicas:
-
Recrie solicitações XHR com curl manualmente, mas certifique-se de copiar todos os cabeçalhos e detalhes, pois todos eles podem fazer a diferença. Alguns consoles de navegador permitem copiar o comando curl
-
Verifique se a solicitação foi negada pelo tratador de CORS, não pela autenticação, filtro de token CSRF, filtros do Dispatcher ou outras camadas de segurança
- Se o tratador de CORS responder com 200, mas o cabeçalho
Access-Control-Allow-Origin
estiver ausente na resposta, procure negações nos logs em DEBUG, emcom.adobe.granite.cors
- Se o tratador de CORS responder com 200, mas o cabeçalho
-
Se o cache do Dispatcher de solicitações CORS estiver habilitado
- Verifique se a configuração
/cache/headers
foi aplicada adispatcher.any
e se o servidor da web foi reiniciado com sucesso - Verifique se o cache foi limpo corretamente após qualquer alteração na configuração de OSGi ou do Dispatcher.
- Verifique se a configuração
-
se necessário, verifique a presença de credenciais de autenticação na solicitação.