內容安全性原則

注意

新的和改進 的 Power Platform 管理中心 現已正式發佈。 我們目前正在更新文件以反映這些更改,因此請回來查看以確保您獲得最新的更新。

目前模型導向和畫布 Power Apps 支援內容安全性原則 (CSP)。 管理員可以控制是否要傳送 CSP 標題,以及在一定程度上控制它包含的內容。 這些設定位於環境層級,這代表一旦開啟,其就會套用至環境中的所有應用程式。

注意

內容安全性原則僅適用於使用 Dataverse 的環境。

CSP 標題值的每個元件都會控制可以下載的資源,並將在Mozilla Developer Network (MDN) 上更詳細地描述。 預設值如下所示:

指示詞 Default value 可自訂
script-src * 'unsafe-inline' 'unsafe-eval'
worker-src 'self' blob:
style-src * 'unsafe-inline'
font-src * data:
frame-ancestors 'self' https://*.powerapps.com .是

此配置導致預設 CSP 為 script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;。 在我們的藍圖中,我們能夠修改目前不可自訂的標題。

先決條件

  • 對於 Dynamics 365 客戶互動應用程式和其他模型導向應用,CSP 僅在線上環境和具有 Dynamics 365 Customer Engagement (on-premises) 版本 9.1 或更高版本的組織中可用。

設定 CSP

可以通過管理中心切換 Power Platform 和配置 CSP。 請務必先 啟用開發/測試環境,因為如果違反策略,啟用 CSP 可能會開始阻止方案。 我們還支援「報告專用模式」,以便更輕鬆地加速生產。

若要設定 CSP:

  1. 登入 Power Platform 系統管理中心
  2. 在導航窗格中,選擇 “管理”,然後在“管理” 窗格中,選擇 “環境”
  3. 在「環境」 頁上,選擇一個環境。
  4. 在命令欄中,選擇 設置
  5. 展開 「產品」,然後選擇 「隱私 + 安全」

下圖顯示設定的預設狀態:

內容安全策略預設設置。

報告

啟用報告 切換控制 模型驅動應用和畫布應用是否發送違規報告。 需要指定終結點才能啟用它。 無論是否已強制執行 CSP,都會將違規報告傳送至此端點 (如果未強制執行 CSP,則使用報告專用模式)。 如需詳細資訊,請參閱報告文件

啟用報告開關「打開」。

實施

對於模型導向和畫布應用程式,強制執行 CSP 是獨立控制的,以提供提供精確的原則控制。 使用模型導向/畫布樞紐來修改預期的應用程式類型。

「強制執行內容安全性原則」開關可開啟指定應用程式類型強制執行的預設原則。 打開此切換開關將會變更此環境中應用程式的行為,以符合該原則。 因此,建議的啟用流程為:

  1. 在開發/測試環境上強制執行。
  2. 在生產中啟用報告專用模式。
  3. 只要沒有違規報告,就在生產中執行。

設定指示

本區段可讓您控制原則中的各個指示詞。 目前只有 frame-ancestors 可以自訂。

配置 CSP 指令。

將預設指令保持開啟狀態,將使用本文先前顯示資料表中指定的預設值。 關閉切換功能可讓管理員指定指令的自訂值,並將其附加至預設值。 以下範例設定 frame-ancestors 的自訂值。 在此範例中,該指令會設為 frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com,表示應用程式可以託管在同一個來源 (https://*.powerapps.comhttps://www.foo.comhttps://www.bar.com) 中,而不是在其他來源中。 使用「添加 按鈕將條目添加到清單中, 使用「刪除」 圖示將其刪除。

設置自定義 CSP 指令。

一般設定

若要使用 Dynamics 365 應用程式進行 Microsoft Teams 整合,請將下列項目新增至 frame-ancestors

  • https://teams.microsoft.com/
  • https://teams.cloud.microsoft/
  • https://msteamstabintegration.dynamics.com/

對於 Dynamics 365 App for Outlook,將以下內容新增至 frame-ancestors

  • 您的 Outlook Web App 首頁來源
  • https://outlook.office.com
  • https://outlook.office365.com

若要在 Power BI 報表中嵌入 Power Apps,請將下列內容新增至 frame-ancestors

  • https://app.powerbi.com
  • https://ms-pbi.pbi.microsoft.com

重要考量

關閉預設指令並使用空白清單儲存完全關閉指示詞,且不會將其做為 CSP 回覆標題中的一部分傳送。

CSP 配置範例

讓我們看幾個 CSP 配置示例。

範例 1 - 報告已關閉

CSP 示例 1.

在範例中:

  • 報告已關閉。
  • 已啟用模型導向強制執行。
    • frame-ancestors 自訂為 https://www.foo.comhttps://www.bar.com
  • 已停用畫布強制執行。

有效的標頭將是:

  • 模型導向應用程式:Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors https://www.foo.com https://www.bar.com;
  • 畫布應用程式:不會傳送 CSP 標題。

範例 2 - 已啟用報告

CSP 示例 2.

在範例中:

  • 報告已開啟。
    • 報告端點設為 https://www.mysite.com/myreportingendpoint
  • 已啟用模型導向強制執行。
    • frame-ancestors 保留為預設值
  • 已停用畫布強制執行。
    • frame-ancestors 自訂為 https://www.baz.com

有效的 CSP 值將是:

  • 模型導向應用程式:Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com; report-uri https://www.mysite.com/myreportingendpoint;
  • 畫布應用程式:Content-Security-Policy-Report-Only: script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors https://www.baz.com; report-uri https://www.mysite.com/myreportingendpoint;

直接修改組織設置

可以通過直接修改以下組織設置來配置 CSP,而無需使用 UI:

  • IsContentSecurityPolicyEnabled 控制是否要在模型導向應用程式中傳送內容安全性原則標題。

  • ContentSecurityPolicyConfiguration 控制 frame-ancestors 部分的值 (如上所示,它設置為 'self' if ContentSecurityPolicyConfiguration 未設置)。 此設置是使用具有以下結構的 JSON 物件定義的– { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }。 此配置轉換為 script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (來自 MDN) HTTP 內容安全性原則 (CSP) frame-ancestor 指令指定可以使用 <frame><iframe><object><embed><applet> 內嵌頁面的有效上層。
  • IsContentSecurityPolicyEnabledForCanvas 控制是否要在畫布應用程式中傳送內容安全性原則標題。

  • ContentSecurityPolicyConfigurationForCanvas 使用中 ContentSecurityPolicyConfiguration所述的相同過程控制畫布的策略。

  • ContentSecurityPolicyReportUri 控制是否應使用報告。 模型導向和畫布應用程式都使用此設定。 如果 IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas 已關閉,則有效字串將使用報告專用模式將違規報告傳送到指定端點。 空字串會停用報告。 如需詳細資訊,請參閱報告文件

在沒有 UI 的情況下設定 CSP

特別是對於不在 Power Platform 系統管理中心的環境,例如內部部署設定,管理員可能希望使用指令碼設定 CSP 以直接修改設定。

啟用沒有 UI 的 CSP

執行以下步驟以啟用沒有 UI 的 CSP:

  • 以具有組織實體更新權限的使用者身分使用模型導向應用程式時,打開瀏覽器開發工具 (系統管理員會是不錯的選擇)。
  • 將以下指令碼貼到主控台並執行。
  • 若要啟用 CSP,請傳遞預設設定 - enableFrameAncestors(["'self'"])
  • 作為允許其他來源嵌入應用程式的範例 - enableFrameAncestors(["*.powerapps.com", "'self'", "abcxyz"])
async function enableFrameAncestors(sources) {
    const baseUrl = Xrm.Utility.getGlobalContext().getClientUrl();

    if (!Array.isArray(sources) || sources.some(s => typeof s !== 'string')) {
        throw new Error('sources must be a string array');
    }

    const orgResponse = await fetch(`${baseUrl}/api/data/v9.1/organizations`);
    if (!orgResponse.ok) throw new Error('Failed to retrieve org info');
    const orgs = await orgResponse.json();
    const { organizationid, contentsecuritypolicyconfiguration, iscontentsecuritypolicyenabled } = orgs.value[0];

    console.log(`Organization Id: ${organizationid}`);
    console.log(`CSP Enabled?: ${iscontentsecuritypolicyenabled}`);
    console.log(`CSP Config: ${contentsecuritypolicyconfiguration}`);

    const orgProperty = prop => `${baseUrl}/api/data/v9.1/organizations(${organizationid})/${prop}`;

    console.log('Updating CSP configuration...')
    const config = {
        'Frame-Ancestor': {
            sources: sources.map(source => ({ source })),
        },
    };
    const cspConfigResponse = await fetch(orgProperty('contentsecuritypolicyconfiguration'), {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            value: JSON.stringify(config),
        }),
    });

    if (!cspConfigResponse.ok) {
        throw new Error('Failed to update csp configuration');
    }
    console.log('Successfully updated CSP configuration!')

    if (iscontentsecuritypolicyenabled) {
        console.log('CSP is already enabled! Skipping update.')
        return;
    }

    console.log('Enabling CSP...')
    const cspEnableResponse = await fetch(orgProperty('iscontentsecuritypolicyenabled'), {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            value: true,
        }),
    });

    if (!cspEnableResponse.ok) {
        throw new Error('Failed to enable csp');
    }
    console.log('Successfully enabled CSP!')
}

禁用沒有 UI 的 CSP

執行以下步驟以禁用沒有 UI 的 CSP:

  • 以具有組織實體更新權限的使用者身分使用模型導向應用程式時,打開瀏覽器開發工具 (系統管理員會是不錯的選擇)。
  • 將以下指令碼貼到主控台並執行。
  • 若要停用 CSP,請將其貼上到主控台:disableCSP()
async function disableCSP() {
    const baseUrl = Xrm.Utility.getGlobalContext().getClientUrl();

    const orgResponse = await fetch(`${baseUrl}/api/data/v9.1/organizations`);
    if (!orgResponse.ok) throw new Error('Failed to retrieve org info');
    const orgs = await orgResponse.json();
    const { organizationid, iscontentsecuritypolicyenabled } = orgs.value[0];

    console.log(`Organization Id: ${organizationid}`);
    console.log(`CSP Enabled?: ${iscontentsecuritypolicyenabled}`);

    const orgProperty = prop => `${baseUrl}/api/data/v9.1/organizations(${organizationid})/${prop}`;

    if (!iscontentsecuritypolicyenabled) {
        console.log('CSP is already disabled! Skipping update.')
        return;
    }

    console.log('Disabling CSP...')
    const cspEnableResponse = await fetch(orgProperty('iscontentsecuritypolicyenabled'), {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            value: false,
        }),
    });

    if (!cspEnableResponse.ok) {
        throw new Error('Failed to disable csp');
    }
    console.log('Successfully disabled CSP!')
}