Chính sách bảo mật nội dung

Chính sách bảo mật nội dung (CSP) hiện được hỗ trợ trong các ứng dụng dựa trên mô hình, canvas và mã. Bài viết này giải thích cách đặt cấu hình CSP cho ứng dụng dựa trên mô hình và canvas. Đối với CSP ứng dụng mã, hãy xem tài liệu về ứng dụng mã. Quản trị viên có thể kiểm soát xem tiêu đề CSP có được gửi hay không và nội dung bên trong ở mức độ nào đó. Các cài đặt ở cấp độ môi trường, có nghĩa là chúng được áp dụng cho tất cả các ứng dụng trong môi trường sau khi được bật.

Lưu ý

Chính sách bảo mật nội dung chỉ áp dụng cho các môi trường sử dụng Dataverse.

Mỗi thành phần của giá trị tiêu đề CSP kiểm soát nội dung có thể tải xuống. Mozilla Developer Network (MDN) cung cấp các mô tả chi tiết hơn. Các giá trị mặc định như sau:

Chỉ thị Giá trị mặc định Có thể tùy chỉnh
tập lệnh-src * 'unsafe-inline' 'unsafe-eval' blob: Không
công nhân-src 'self' blob: Không
phong cách-src * 'unsafe-inline' blob: Không
phông chữ-src * data: Không
khung-tổ-hậu 'self' https://*.powerapps.com

Cấu hình này tạo ra CSP mặc định là script-src * 'unsafe-inline' 'unsafe-eval' blob: ; worker-src 'self' blob:; style-src * 'unsafe-inline' blob:; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;.

Chế độ nghiêm ngặt

Nút chuyển đổi CSP nghiêm ngặt tạo ra một CSP hầu như không bao gồm các ký tự đại diện hoặc lệnh không an toàn, chẳng hạn như unsafe-inline. Khi bạn bật CSP nghiêm ngặt, các chỉ thị trước đó sẽ trở thành các chỉ thị sau được nêu chi tiết trong phần này. Ký hiệu có <platform> nghĩa là các miền nền tảng được cung cấp theo yêu cầu của sản phẩm. Các miền trong mục này có thể thay đổi theo thời gian khi sản phẩm phát triển.

Chỉ thị Giá trị mặc định (dựa trên mô hình) Giá trị mặc định (canvas) Có thể tùy chỉnh
tập lệnh-src 'self' blob: <platform>' 'self' <platform>'
công nhân-src 'self' blob: 'self' blob: Không
phong cách-src 'self' 'unsafe-inline' blob: <platform> 'self' 'unsafe-inline' <platform>
phông chữ-src 'self' data: <platform> 'self' data: <platform>
khung-tổ-hậu 'self' https://*.powerapps.com 'self' https://*.powerapps.com
hình ảnh-src 'self' blob: data: <platform> 'self' data: <platform>
kết nối-src 'self' blob: data: wss: <platform> 'self' blob: <platform>
khung-src 'self' blob: <platform> 'self' <platform>
cơ sở-uri 'none' Không có Không
hình thức-hành động <platform> Không có
mặc định-src 'self' 'self' Không

Điều kiện tiên quyết

Đối với ứng dụng Dynamics 365 Customer Engagement và các ứng dụng dựa trên mô hình khác, CSP chỉ khả dụng trong môi trường trực tuyến và trong các tổ chức có Dynamics 365 Customer Engagement (on-premises), phiên bản 9.1 trở lên.

Định cấu hình CSP

Bạn có thể chuyển đổi và cấu hình CSP thông qua trung tâm quản trị. Power Platform Trước tiên, điều quan trọng là phải bật môi trường phát triển/kiểm thử vì việc bật CSP có thể bắt đầu chặn các tình huống nếu chính sách bị vi phạm. Trung tâm quản trị cũng hỗ trợ chế độ chỉ báo cáo để cho phép tăng cường sản xuất dễ dàng hơn.

Thực hiện các bước sau để định cấu hình CSP:

  1. Đăng nhập vào Trung tâm quản trị Power Platform.
  2. Trong ngăn điều hướng, chọn Quản lý. Trong ngăn Quản lý , chọn Môi trường.
  3. Trên trang Môi trường , hãy chọn một môi trường.
  4. Trên thanh lệnh, chọn Cài đặt.
  5. Mở rộng Sản phẩm, sau đó chọn Quyền riêng tư + Bảo mật.

Hình ảnh sau đây hiển thị trạng thái mặc định của các cài đặt:

Cài đặt mặc định của chính sách bảo mật nội dung.

Báo cáo

Nút chuyển đổi Bật báo cáo điều khiển việc ứng dụng dựa trên mô hình và ứng dụng canvas có gửi báo cáo vi phạm hay không. Để kích hoạt tính năng này, hãy chỉ định một điểm cuối. Ứng dụng sẽ gửi báo cáo vi phạm đến điểm cuối này bất kể CSP có được thực thi hay không. Nếu CSP không được thực thi, ứng dụng sẽ sử dụng chế độ chỉ báo cáo. Để biết thêm thông tin, hãy xem hướng dẫn sử dụng báo cáo.

Bật nút báo cáo.

Thực thi

Việc thực thi CSP được kiểm soát độc lập đối với các ứng dụng canvas và dựa trên mô hình để cung cấp khả năng kiểm soát chi tiết đối với các chính sách. Sử dụng pivot dựa trên mô hình/canvas để sửa đổi loại ứng dụng dự kiến.

Nút bật/tắt Thực thi chính sách bảo mật nội dung bật chính sách mặc định để thực thi cho loại ứng dụng nhất định. Bật nút chuyển đổi này sẽ thay đổi hành vi của các ứng dụng trong môi trường này để tuân thủ chính sách. Do đó, hãy làm theo quy trình hỗ trợ được đề xuất sau:

  1. Thực thi chính sách trên môi trường phát triển hoặc thử nghiệm.
  2. Bật chế độ chỉ báo cáo trong quy trình sản xuất.
  3. Thực thi chính sách trong sản xuất khi không có vi phạm nào được báo cáo.

Đặt cấu hình chỉ thị

Phần Định cấu hình lệnh cho phép bạn kiểm soát các lệnh riêng lẻ trong chính sách. Hiện tại, bạn chỉ có thể tùy chỉnh frame-ancestors chỉ thị.

Cấu hình chỉ thị CSP.

Nếu bạn để chỉ thị mặc định được bật, bạn sử dụng giá trị mặc định được chỉ định trong bảng. Nếu tắt nút bật/tắt, bạn có thể chỉ định các giá trị tùy chỉnh cho chỉ thị và thêm chúng vào giá trị mặc định. Ví dụ sau đây đặt các giá trị tùy chỉnh cho frame-ancestors. Chỉ thị được đặt thành frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com trong ví dụ này. Cài đặt này có nghĩa là ứng dụng có thể được lưu trữ ở cùng một nguồn gốc, https://*.powerapps.com, https://www.foo.comhttps://www.bar.com, nhưng không phải ở các nguồn khác. Sử dụng nút Thêm để thêm mục vào danh sách và biểu tượng Xóa để xóa chúng.

Thiết lập chỉ thị CSP tùy chỉnh.

Cấu hình phổ biến

Để tích hợp Microsoft Teams bằng ứng dụng Dynamics 365, hãy thêm thông tin sau vào frame-ancestors:

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

Đối với Ứng dụng Dynamics 365 dành cho Outlook, hãy thêm thông tin sau vào frame-ancestors:

  • Nguồn gốc trang chủ Outlook Web App của bạn
  • https://outlook.office.com
  • https://outlook.office365.com

Để nhúng Power Apps vào báo cáo Power BI, hãy thêm thông tin sau vào frame-ancestors:

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

Những điều quan trọng cần cân nhắc

Việc tắt chỉ thị mặc định và lưu bằng danh sách trống sẽ tắt hoàn toàn chỉ thị và không gửi chỉ thị đó trong tiêu đề phản hồi CSP.

Ví dụ cấu hình CSP

Dưới đây là một vài ví dụ về cấu hình CSP.

Ví dụ 1 - báo cáo đã tắt

CSP example 1, dựa trên mô hình

Ví dụ CSP 1, canvas

Trong ví dụ:

  • Báo cáo bị tắt.
  • Đã bật tính năng thực thi dựa trên mô hình.
    • frame-ancestors được tùy chỉnh để https://www.contoso.comhttps://www.fabrikam.com.
  • Tính năng thực thi canvas bị tắt.

Các tiêu đề hiệu quả là:

  • Ứng dụng dựa trên mô hình: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline' :blob; font-src * data:; frame-ancestors https://www.contoso.com https://www.fabrikam.com;
  • Ứng dụng canvas: Tiêu đề CSP không được gửi.

Ví dụ 2 - báo cáo được bật

CSP ví dụ 2, dựa trên mô hình

Ví dụ CSP 2, canvas

Trong ví dụ:

  • Báo cáo được bật.
    • Điểm cuối báo cáo được đặt thành https://contoso.com/reporting-endpoint
  • Đã bật tính năng thực thi dựa trên mô hình.
    • frame-ancestors được giữ nguyên mặc định
  • Tính năng thực thi canvas bị tắt.
    • frame-ancestors được tùy chỉnh để https://www.contoso.com

Các giá trị CSP hiệu quả là:

  • Ứng dụng dựa trên mô hình: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob:; worker-src 'self' blob:; style-src * 'unsafe-inline' blob:; font-src * data:; frame-ancestors 'self' https://*.powerapps.com; report-uri https://contoso.com/reporting-endpoint;
  • Ứng dụng canvas: 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.contoso.com; report-uri https://contoso.com/reporting-endpoint;

Sửa đổi cài đặt tổ chức trực tiếp

Bạn có thể cấu hình CSP mà không cần sử dụng UI bằng cách sửa đổi trực tiếp các cài đặt tổ chức sau:

  • IsContentSecurityPolicyEnabled kiểm soát xem tiêu đề Content-Security-Policy có được gửi trong các ứng dụng dựa trên mô hình hay không.

  • ContentSecurityPolicyConfiguration kiểm soát giá trị của phần tổ tiên khung (như đã thấy trước đó, phần này được đặt thành 'self' nếu ContentSecurityPolicyConfiguration không được đặt). Xác định cài đặt này bằng cách sử dụng đối tượng JSON với cấu trúc sau - { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Cấu hình này được dịch thành script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline' blob:; font-src * data:; frame-ancestors 'foo' 'bar';

    • (Từ MDN) Chỉ thị frame-ancestors của HTTP Content-Security-Policy (CSP) chỉ định phần tử cha hợp lệ có thể nhúng trang bằng cách sử dụng <frame>, <iframe>, <object>, <embed> hoặc <applet>.
  • IsContentSecurityPolicyEnabledForCanvas kiểm soát xem tiêu đề Content-Security-Policy có được gửi trong ứng dụng canvas hay không.

  • ContentSecurityPolicyConfigurationForCanvas kiểm soát chính sách cho canvas bằng cùng quy trình được mô tả trong ContentSecurityPolicyConfiguration.

  • ContentSecurityPolicyReportUri kiểm soát việc có nên sử dụng báo cáo hay không. Cả ứng dụng dựa trên mô hình và ứng dụng canvas đều dùng thiết đặt này. Một chuỗi hợp lệ sẽ gửi báo cáo vi phạm đến điểm cuối được chỉ định, sử dụng chế độ chỉ báo cáo nếu IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas bị tắt. Một chuỗi rỗng sẽ vô hiệu hóa báo cáo. Để biết thêm thông tin, hãy xem hướng dẫn sử dụng báo cáo.

Đặt cấu hình mà không có giao diện người dùng

Đặc biệt đối với những môi trường không có trong trung tâm quản trị Power Platform, chẳng hạn như cấu hình tại chỗ, quản trị viên nên đặt cấu hình CSP bằng tập lệnh để trực tiếp sửa đổi thiết đặt.

Bật CSP mà không cần UI

Thực hiện các bước sau để bật CSP mà không cần UI:

  • Mở công cụ phát triển trình duyệt trong khi dùng ứng dụng dựa trên mô hình với tư cách là người dùng có đặc quyền cập nhật thực thể tổ chức (Quản trị viên hệ thống là một lựa chọn thích hợp).
  • Dán và thực thi đoạn mã sau vào bảng điều khiển.
  • Để bật CSP, hãy chuyển cấu hình mặc định - enableFrameAncestors(["'self'"])
  • Ví dụ về việc cho phép các nguồn gốc khác nhúng ứng dụng - 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!')
}

Tắt CSP mà không có UI

Thực hiện các bước sau để tắt CSP mà không cần UI:

  • Mở công cụ phát triển trình duyệt trong khi dùng ứng dụng dựa trên mô hình với tư cách là người dùng có đặc quyền cập nhật thực thể tổ chức (Quản trị viên hệ thống là một lựa chọn thích hợp).
  • Dán và thực thi đoạn mã sau vào bảng điều khiển.
  • Để tắt CSP, hãy dán vào bảng điều khiển: 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!')
}