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

Adobe Experience Manager的跨原始資源共用(CORS)可協助非AEM Web屬性對AEM進行使用者端呼叫(不論已驗證或未驗證),以擷取內容或直接與AEM互動。

本檔案中概述的OSGI設定足以用於:

  1. AEM Publish上的單一來源資源共用
  2. AEM作者的CORS存取權

如果AEM Publish上需要多來源CORS存取,請參閱本檔案

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

CORS設定在AEM中作為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)

原則選擇

原則是透過比較

  • 具有Origin請求標頭的Allowed Origin
  • Allowed Paths (含要求路徑)。

系統會使用符合這些值的第一個原則。 如果找不到任何專案,則會拒絕任何CORS要求。

如果完全未設定原則,則不會回應CORS要求,因為處理常式已停用,因此會有效拒絕(只要伺服器的其他模組沒有回應CORS)。

原則屬性

允許的來源

  • "alloworigin" <origin> | *
  • origin引數的清單,指定可存取資源的URI。 對於沒有認證的請求,伺服器可以指定*作為萬用字元,從而允許任何來源存取資源。 絕對不建議在生產環境中使用Allow-Origin: *,因為它允許所有外國(即攻擊者)網站提出瀏覽器嚴禁不含CORS的要求。

允許的來源(Regexp)

  • "alloworiginregexp" <regexp>
  • 指定可存取資源之URI的regexp規則運算式清單。 規則運算式若未小心建置,可能會造成非預期的相符專案,讓攻擊者使用也會符合原則的自訂網域名稱。 ​通常建議使用alloworigin為每個特定的原始主機名稱設定不同的原則,即使這表示重複設定其他原則屬性。 不同的起源往往具有不同的生命週期和要求,因此有利於清晰的分離效果。

允許的路徑

  • "allowedpaths" <regexp>
  • 指定原則套用之資源路徑的regexp規則運算式清單。

公開的標頭

  • "exposedheaders" <header>
  • 標頭引數清單,指示瀏覽器可存取的回應標頭。 若為CORS請求(非預檢),若非空白,這些值會複製到Access-Control-Expose-Headers回應標頭。 之後,瀏覽器即可存取清單中的值(標頭名稱);若沒有清單,瀏覽器就無法讀取這些標頭。

最大年齡

  • "maxage" <seconds>
  • seconds引數,指出可快取預檢要求結果的時間長度。

支援的標頭

  • "supportedheaders" <header>
  • header引數的清單,指出可在發出實際請求時使用哪些HTTP請求標頭。

允許的方法

  • "supportedmethods"
  • 方法引數清單,指示提出實際要求時可以使用哪些HTTP方法。

支援認證

  • "supportscredentials" <boolean>
  • 指出對要求的回應是否可向瀏覽器公開的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標頭。

一般而言,在Dispatcher快取內容的考量也適用於在Dispatcher快取CORS回應標頭。 下表定義何時可以快取CORS個標題(以及CORS個請求)。

可快取
環境
驗證狀態
解釋
AEM 發佈
已驗證
AEM Author上的Dispatcher快取僅限於靜態的非編寫資產。 這使得在AEM Author上快取大部分資源(包括HTTP回應標頭)變得困難和不實際。
AEM 發佈
已驗證
避免在已驗證的請求上快取CORS標頭。 這符合不快取已驗證請求的常見指南,因為很難判斷請求使用者的驗證/授權狀態將如何影響傳送的資源。
AEM 發佈
匿名
Dispatcher中可快取的匿名請求也可以快取其回應標頭,以確保未來的CORS請求可以存取快取的內容。 AEM Publish 上的任何CORS組態變更都必須,之後才會讓受影響的快取資源失效。 最佳實務指示程式碼或設定部署會清除Dispatcher快取,因為很難判斷哪些快取內容可能會受到影響。

允許CORS要求標頭

若要允許必要的HTTP要求標頭傳遞至AEM進行處理,必須在Dispatcher的/clientheaders設定中允許這些標頭。

/clientheaders {
   ...
   "Origin"
   "Access-Control-Request-Method"
   "Access-Control-Request-Headers"
}

快取CORS回應標頭

若要允許在快取的內容上快取及提供CORS標頭,請將下列/cache /headers設定新增至AEM Publish 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"
        }
    ...
    }
...
}

請記得在變更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,且網頁伺服器已成功重新啟動
    • 請確保在任何OSGi或dispatcher.any設定變更後已正確清除快取。
  • 如果需要,請檢查請求中是否存在驗證認證。

支援材料

recommendation-more-help
c92bdb17-1e49-4e76-bcdd-89e4f85f45e6