了解跨源资源共享(CORS)
Adobe Experience Manager的跨源资源共享(CORS)便于非AEM Web属性对AEM进行客户端调用(无论是否经过身份验证),以获取内容或直接与AEM交互。
本文档中概述的OSGI配置足以满足以下要求:
- AEM Publish上的单源资源共享
- 对AEM Author的CORS访问权限
如果AEM Publish上需要多源CORS访问,请参阅 本文档.
AdobeGranite跨源资源共享策略OSGi配置
CORS配置在AEM中作为OSGi配置工厂进行管理,每个策略都表示为工厂的一个实例。
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
)
策略选择
通过比较
Allowed Origin
使用Origin
请求标头- 和
Allowed Paths
请求路径。
将使用匹配这些值的第一个策略。 如果未找到,则任何 CORS 请求被拒绝。
如果未配置任何策略, CORS 由于处理程序被禁用,因此请求也不会得到应答 — 只要服务器的其他模块没有响应 CORS.
策略属性
允许的源
"alloworigin" <origin> | *
- 列表
origin
指定可以访问资源的URI的参数。 对于没有凭据的请求,服务器可以指定 * 作为通配符,从而允许任何源访问资源。 绝对不建议使用Allow-Origin: *
因为它允许每个外国(即攻击者)网站发出不带CORS的请求被浏览器严格禁止。
允许的源(正则表达式)
"alloworiginregexp" <regexp>
- 列表
regexp
指定可以访问资源的URI的正则表达式。 如果不仔细构建,正则表达式可能会导致意外匹配,使得攻击者能够使用也与该策略匹配的自定义域名。 通常建议为每个特定的源主机名使用单独的策略alloworigin
,即使这意味着重复配置其他策略属性也是如此。 不同的起源往往具有不同的生命周期和要求,从而有利于清晰的分离。
允许的路径
"allowedpaths" <regexp>
- 列表
regexp
指定策略适用的资源路径的正则表达式。
公开的标题
"exposedheaders" <header>
- 标头参数列表,指示允许浏览器访问的响应标头。 对于CORS请求(非预检),如果不为空,这些值将复制到
Access-Control-Expose-Headers
响应标头。 随后,浏览器将能够访问列表中的值(标头名称);如果没有这些标头,浏览器将无法读取这些标头。
最长使用期限
"maxage" <seconds>
- A
seconds
指示可缓存预检请求结果的时间的参数。
支持的标头
"supportedheaders" <header>
- 列表
header
指示发出实际请求时可以使用哪些HTTP请求标头的参数。
允许的方法
"supportedmethods"
- 方法参数列表,指示在发出实际请求时可以使用哪些HTTP方法。
支持凭据
"supportscredentials" <boolean>
- A
boolean
指示对请求的响应是否可以向浏览器公开。 当用作对飞行前请求的响应的一部分时,这指示是否可以使用凭据发出实际请求。
示例配置
网站1是一个基本、匿名访问、只读的场景,其中内容通过以下方式使用 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"
]
}
站点2比较复杂,需要进行授权和异动(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"
]
}
Dispatcher缓存顾虑和配置 dispatcher-caching-concerns-and-configuration
从Dispatcher 4.1.1开始,可以缓存响应标头。 这使得可以缓存 CORS 标头以及 CORS-requested resources(请求为匿名)。
通常,在Dispatcher缓存内容的相同考虑因素也可以应用于在Dispatcher缓存CORS响应标头。 下表定义何时 CORS 标头(以及因此 CORS 请求)进行缓存。
允许CORS请求标头
允许必需的 要传递到AEM以进行处理的HTTP请求标头,它们必须在Dispatcher的 /clientheaders
配置。
/clientheaders {
...
"Origin"
"Access-Control-Request-Method"
"Access-Control-Request-Headers"
}
缓存CORS响应标头
要允许在缓存的内容上缓存和提供CORS标头,请添加以下内容 /cache /headers配置 到AEM发布 dispatcher.any
文件。
/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"
}
...
}
...
}
请记住 重新启动Web服务器应用程序 在对进行更改之后 dispatcher.any
文件。
可能需要完全清除缓存,以确保在之后的下一个请求中正确缓存标头 /cache/headers
配置更新。
CORS疑难解答
日志记录位于 com.adobe.granite.cors
:
- 启用
DEBUG
查看有关原因 CORS 请求被拒绝 - 启用
TRACE
查看有关通过CORS处理程序处理的所有请求的详细信息
提示:
-
使用curl手动重新创建XHR请求,但请确保复制所有标题和详细信息,因为每个标题和详细信息都可以产生影响;某些浏览器控制台允许复制curl命令
-
验证请求是否被CORS处理程序拒绝,而不是被身份验证、CSRF令牌过滤器、调度程序过滤器或其他安全层拒绝
- 如果CORS处理程序使用200进行响应,但
Access-Control-Allow-Origin
响应中不存在标头,请查看日志中的拒绝信息 DEBUG 在com.adobe.granite.cors
- 如果CORS处理程序使用200进行响应,但
-
如果Dispatcher缓存 CORS 请求已启用
- 确保
/cache/headers
配置应用于dispatcher.any
并且Web服务器已成功重新启动 - 确保在任何OSGi或dispatcher.any配置更改后正确清除缓存。
- 确保
-
如果需要,检查请求中是否存在身份验证凭据。