Entender o compartilhamento de recursos entre origens (CORS)
Compartilhamento de recursos entre origens da Adobe Experience Manager (CORS) facilita as propriedades da Web que não são do AEM para fazer chamadas do lado do cliente para o AEM, tanto autenticadas quanto não autenticadas, para buscar conteúdo ou interagir diretamente com o AEM.
A configuração OSGI descrita neste documento é suficiente para:
- Compartilhamento de recursos de origem única na publicação do AEM
- Acesso do CORS ao AEM Author
Se o acesso ao CORS de várias origens for necessário para AEM Publish, consulte esta documentação.
Configuração 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 OSGi no AEM, com cada política sendo 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 as
Allowed Origin
com oOrigin
cabeçalho da solicitação- e
Allowed Paths
com o caminho da solicitação.
A primeira política correspondente a esses valores é usada. Se nenhum for encontrado, qualquer CORS solicitação negada.
Se nenhuma política estiver configurada, CORS as solicitações também não serão respondidas, pois o manipulador está desativado e, portanto, efetivamente negado - desde que nenhum outro módulo do servidor responda a CORS.
Propriedades da política
Origens permitidas
"alloworigin" <origin> | *
- Lista de
origin
parâmetros 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: *
em produção, pois permite que cada site estrangeiro (ou seja, invasor) faça solicitações que sem o CORS sejam estritamente proibidas pelos navegadores.
Origens permitidas (Regexp)
"alloworiginregexp" <regexp>
- Lista de
regexp
expressões regulares que especificam URIs que podem acessar o recurso. 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. Geralmente, é recomendável ter políticas separadas para cada nome de host de origem específico, usandoalloworigin
, mesmo que isso signifique a configuração repetida das outras propriedades de política. Diferentes origens tendem a ter diferentes ciclos de vida e requisitos, beneficiando assim de uma separação clara.
Caminhos permitidos
"allowedpaths" <regexp>
- Lista de
regexp
expressões regulares que especificam 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 do CORS (não antes do voo), se não estiver vazio, esses valores serão copiados para o
Access-Control-Expose-Headers
cabeçalho de resposta. Os valores na lista (nomes de cabeçalho) são então acessíveis ao navegador; sem ela, esses cabeçalhos não são legíveis pelo navegador.
Idade máxima
"maxage" <seconds>
- A
seconds
parâmetro que indica por quanto tempo os resultados de uma solicitação antes do voo podem ser armazenados em cache.
Cabeçalhos suportados
"supportedheaders" <header>
- Lista de
header
parâmetros que indicam 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.
Suporta Credenciais
"supportscredentials" <boolean>
- A
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 antes do voo, indica se a solicitação real pode ou não ser feita usando credenciais.
Exemplo de configurações
O Site 1 é um cenário básico, acessível anonimamente e somente leitura, em que o conteúdo é consumido via GET solicitações:
{
"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"
]
}
Preocupações 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 armazenar em cache CORS cabeçalhos ao longo do CORS-recursos solicitados, desde que a solicitação seja anônima.
Geralmente, as mesmas considerações para armazenamento em cache de 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 CORS cabeçalhos (e assim CORS solicitações) podem ser armazenadas em cache.
Permitir cabeçalhos de solicitação CORS
Para permitir as Cabeçalhos de solicitação HTTP para transmitir ao AEM para processamento, eles devem ter permissão no do Dispatcher /clientheaders
configuração.
/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 CORS no conteúdo em cache, adicione o seguinte /cache /configuração de cabeçalhos ao AEM Publish dispatcher.any
arquivo.
/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 web depois de fazer alterações no dispatcher.any
arquivo.
Provavelmente, é necessário limpar totalmente o cache para garantir que os cabeçalhos sejam armazenados em cache corretamente na próxima solicitação após um /cache/headers
atualização de configuração.
Solução de problemas do CORS
O registro está disponível em com.adobe.granite.cors
:
- habilitar
DEBUG
para ver detalhes sobre por que uma CORS a solicitação foi negada - habilitar
TRACE
para ver detalhes sobre todas as solicitações que passam pelo manipulador CORS
Dicas:
-
Recriar manualmente solicitações XHR usando curl, mas certifique-se de copiar todos os cabeçalhos e detalhes, pois cada um pode fazer a diferença; alguns consoles do navegador permitem copiar o comando curl
-
Verifique se a solicitação foi negada pelo manipulador CORS e não pela autenticação, filtro de token CSRF, filtros de dispatcher ou outras camadas de segurança
- Se o manipulador CORS responder com 200, mas
Access-Control-Allow-Origin
cabeçalho estiver ausente na resposta, revise os logs para negações em DEBUG incom.adobe.granite.cors
- Se o manipulador CORS responder com 200, mas
-
Se o armazenamento em cache do dispatcher de CORS solicitações está habilitado
- Assegure a
/cache/headers
a configuração é aplicada adispatcher.any
e o servidor Web foi reiniciado com êxito - Verifique se o cache foi limpo corretamente após qualquer alteração de configuração de OSGi ou dispatcher.
- Assegure a
-
se necessário, verifique a presença de credenciais de autenticação na solicitação.