了解跨原始資源共用(CORS)

Adobe Experience Manager的跨原始資源共用(CORS)方便了非AEM Web屬性向AEM進行用戶端呼叫(驗證和未驗證),以擷取內容或直接與AEM互動。

AdobeGranite跨原始資源共用原則OSGi設定

在AEM中,CORS設定會以OSGi設定工廠的形式管理,而每個政策會以工廠的一個例項來表示。

  • http://<host>:<port>/system/console/configMgr > Adobe Granite Cross Origin Resource Sharing Policy

AdobeGranite跨原始資源共用原則OSGi設定

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的要求,都嚴禁瀏覽器使用。

允許的原始項(Regexp)

  • "alloworiginregexp" <regexp>
  • regexp規則運算式清單,這些運算式指定可訪問資源的URI。 如果未仔細構建規則表達式,則可能導致意外匹配,使得攻擊者能夠使用與策略匹配的自定義域名。 通常建議使用為每個特定源主機名稱分別設定策略,即 alloworigin使這意味著重複配置其他策略屬性。不同的起源往往具有不同的生命週期和要求,因此從明確的分離中受益。

允許的路徑

  • "allowedpaths" <regexp>
  • regexp規則運算式清單,指定策略應用的資源路徑。

公開的標題

  • "exposedheaders" <header>
  • 指示瀏覽器可存取之請求標題的標題參數清單。

最大年齡

  • "maxage" <seconds>
  • seconds參數,指出可快取飛行前請求結果的時間長度。

支援的標題

  • "supportedheaders" <header>
  • header參數清單,指出在提出實際請求時可以使用哪些HTTP標題。

允許的方法

  • "supportedmethods"
  • 方法參數清單,指出在提出實際請求時可使用哪些HTTP方法。

支援憑據

  • "supportscredentials" <boolean>
  • boolean表示是否可向瀏覽器公開要求回應。 當用作飛行前請求的回應時,這表示是否可使用憑證來提出實際請求。

組態範例

網站1是匿名存取的基本唯讀案例,其中內容是透過GET請求使用:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="sling:OsgiConfig"
    alloworigin="[https://site1.com]"
    alloworiginregexp="[]"
    allowedpaths="[/content/site1/.*]"
    exposedheaders="[]"
    maxage="{Long}1800"
    supportedheaders="[Origin,Accept,X-Requested-With,Content-Type,
Access-Control-Request-Method,Access-Control-Request-Headers]"
    supportedmethods="[GET]"
    supportscredentials="{Boolean}false"
/>

站點2更複雜,需要授權和不安全的請求:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="sling:OsgiConfig"
    alloworigin="[https://site2.com]"
    alloworiginregexp="[]"
    allowedpaths="[/content/site2/.*,/libs/granite/csrf/token.json]"
    exposedheaders="[]"
    maxage="{Long}1800"
    supportedheaders="[Origin,Accept,X-Requested-With,Content-Type,
Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,CSRF-Token]"
    supportedmethods="[GET,HEAD,POST,DELETE,OPTIONS,PUT]"
    supportscredentials="{Boolean}true"
/>

Dispatcher快取考量事項和設定

從Dispatcher 4.1.1+回應標頭開始,可以快取。 這樣,只要請求是匿名的,就可以將CORS標頭與CORS請求的資源一起快取。

一般而言,在Dispatcher快取內容時,相同的考量可套用至Dispatcher快取CORS回應標題。 下表定義了可快取CORS標題(以及CORS請求)的時間。

可快取 環境 驗證狀態 說明
AEM 發佈 已驗證 AEM Author上的Dispatcher快取限於靜態、非製作的資產。 這樣就很難且不切實際地在AEM作者上快取大部分資源,包括HTTP回應標題。
AEM 發佈 已驗證 避免在已驗證的請求上快取CORS標題。 這符合未快取已驗證請求的一般指引,因為很難判斷要求使用者的驗證/授權狀態將如何影響傳送的資源。
AEM 發佈 匿名 在Dispatcher可快取的匿名請求也可以快取其回應標頭,以確保未來的CORS請求可存取快取的內容。 AEM發佈​上的任何CORS組態變更都必須,之後受影響之快取資源的失效。 最佳實務是要清除調度程式快取的程式碼或設定部署,因為很難判斷會影響哪些快取內容。

若要允許快取CORS標頭,請將下列設定新增至所有支援的AEM Publish dispatcher.any檔案。

/cache { 
  ...
  /headers {
      "Origin"
      "Access-Control-Allow-Origin"
      "Access-Control-Expose-Headers"
      "Access-Control-Max-Age"
      "Access-Control-Allow-Credentials"
      "Access-Control-Allow-Methods"
      "Access-Control-Allow-Headers"
  }
  ...
}

dispatcher.any檔案進行更改後,請記得​重新啟動Web伺服器應用程式

/cache/headers組態更新後,可能需要完全清除快取,以確保在下一個要求時已適當快取標題。

疑難排解CORS

記錄功能可在com.adobe.granite.cors下使用:

  • 啟用DEBUG以查看CORS請求被拒絕的詳細資訊
  • 啟用TRACE以查看有關通過CORS處理程式的所有請求的詳細資訊

提示:

  • 使用curl手動重新建立XHR請求,但請務必複製所有標題和詳細資訊,因為每個標題和詳細資訊都可能有所差異;某些瀏覽器主控台可複製curl命令
  • 驗證請求是否被CORS處理常式拒絕,而不是由驗證、CSRF代號篩選器、Dispatcher篩選器或其他安全層拒絕
    • 如果CORS處理常式以200回應,但回應中缺少Access-Control-Allow-Origin標題,請檢閱com.adobe.granite.cors中DEBUG底下的拒絕記錄
  • 如果已啟用CORS請求的Dispatcher快取
    • 確保/cache/headers配置已應用到dispatcher.any,並且Web伺服器已成功重新啟動
    • 在任何OSGi或dispatcher.any設定變更後,請確定已正確清除快取。
  • 如果需要,請檢查請求上是否存在身份驗證憑據。

支援材料

本頁內容