共用方式為


內容安全性原則

注意

全新改進的 Power Platform 系統管理中心現已可公開預覽! 我們設計的新系統管理中心更易於使用,具有面向任務的導覽,可幫助您更快地實現特定結果。 隨著新的 Power Platform 系統管理中心正式發佈,我們將發佈新的和更新的文件。

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

注意

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

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

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

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

必要條件

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

正在設定 CSP

可透過 Power Platform 系統管理中心切換和設定 CSP。 先在開發/測試環境中啟用非常重要,因為如果違反原則,啟用 CSP 可能會開始封鎖情境。 我們還支援「報告專用模式」,以便更輕鬆地加速生產。

若要設定 CSP,請瀏覽至 Power Platform 系統管理中心 - >環境 - >設定 - >隱私權 + 安全性。 下圖顯示設定的預設狀態:

內容安全性原則預設設定

回報

「啟用報告」切換會控制模型導向應用程式和畫布應用程式是否傳送違規報告。 若啟用它,則需要指定端點。 無論是否已強制執行 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 設定範例:

範例 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;

組織設定

您可以直接修改下列組織設定,以在不使用 UI 的情況下設定 CSP:

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

  • ontentSecurityPolicyConfiguration 控制 frame-ancestors 部分的值 (如上所示,如果未設定 ContentSecurityPolicyConfiguration,則將其設為 'self')。 此設定是由具有下列結構的 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

步驟:

  • 以具有組織實體更新權限的使用者身分使用模型導向應用程式時,打開瀏覽器開發工具 (系統管理員會是不錯的選擇)。
  • 將以下指令碼貼上至主控台並執行。
  • 若要啟用 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

步驟:

  • 以具有組織實體更新權限的使用者身分使用模型導向應用程式時,打開瀏覽器開發工具 (系統管理員會是不錯的選擇)。
  • 將以下指令碼貼到主控台並執行。
  • 若要停用 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!')
}