內容安全性原則

內容安全性原則 (CSP) 目前在模型導向 Power Apps 中透過兩個組織實體屬性獲得支援,這些屬性可控制是否傳送 CSP 標題以及在一定程度上控制其包含的內容。 此設定位於環境層即,這代表一旦打開,其就會套用至環境中的所有應用程式。

備註

目前僅在模型導向應用程式中才支援 CSP。 畫布應用程式支援將於 2022 年夏季推出公開預覽版。

  • IsContentSecurityPolicyEnabled 控制是否要在基本應用程式頁面 (main.aspx) 中傳送內容安全性原則標題。 根據預設,標題將設為 script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self';。 此標題值的每個元件都會控制可以下載的資源,並將在Mozilla Developer Network (MDN) 上更詳細地描述:
  • ContentSecurityPolicyConfiguration 控制 frame-ancestors 部分的值 (如上所示,如果未設定 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> 內嵌頁面的有效上層。

正在設定 CSP

目前沒有用來編輯這些屬性的 UI,但是我們計畫在未來的 Power Platform 管理中心公開這些屬性。 同時,您可以使用以下指令碼來啟用和更新 frame-ancestors 屬性。 先在開發/測試環境中啟用非常重要,因為如果違反原則,啟用此屬性可能會無法下載資產。 我們計畫在未來支援「僅報表模式」,以便更輕鬆地加速生產。

正在啟用 CSP

步驟:

  • 以具有組織實體更新權限的使用者身分使用模型導向應用程式時,打開瀏覽器開發工具 (系統管理員會是不錯的選擇)。
  • 將以下指令碼貼上至主控台並執行。
  • 若只要啟用 CSP,請傳遞預設設定 - enableFrameAncestors(["'self'"])
  • 啟用其他來源內嵌應用程式的範例 - enableFrameAncestors(["*.powerapps.com", "'self'", "abcxyz"])
async function enableFrameAncestors(sources) {
     if (!Array.isArray(sources) || sources.some(s => typeof s !== 'string')) {
        throw new Error('sources must be a string array');
    }

    const orgResponse = await fetch('/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 => `/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!')
}

正在停用 CSP

步驟:

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

備註

是否能請您告知您偏好的慣用文件語言? 請填寫問卷。 (請注意,本問卷為英文版)

完成問卷大約需要七分鐘。 本問卷將不會收集個人資料 (隱私權聲明)。