مشاركة عبر


سياسة أمان المحتوى

نهج أمان المحتوى (CSP) مدعوم حاليا في تطبيقات النماذج واللوحات والرمز. تشرح هذه المقالة كيفية تكوين CSP للتطبيقات المستندة إلى النموذج واللوحة. للحصول على CSP لتطبيقات التعليمات البرمجية، راجع وثائق تطبيقات التعليمات البرمجية. يمكن للمسؤولين التحكم في إرسال رأس CSP وما يحتويه، إلى حد ما. تكون الإعدادات على مستوى البيئة، مما يعني أنها يتم تطبيقها على جميع التطبيقات في البيئة بمجرد تشغيلها.

‏‫ملاحظة‬

لا تنطبق سياسة أمان المحتوى إلا على البيئات باستخدام Dataverse.

يتحكم كل مكون من قيمة رأس CSP في الأصول التي يمكن تنزيلها. توفر شبكة Mozilla Developer Network (MDN) أوصافا أكثر تفصيلا. القيم الافتراضية هي كما يلي:

التوجيه القيمة الافتراضية قابل للتخصيص
script-src * 'unsafe-inline' 'unsafe-eval' blob: لا
worker-src 'self' blob: لا
style-src * 'unsafe-inline' لا
font-src * data: لا
frame-ancestors 'self' https://*.powerapps.com نعم

ينتج عن هذا التكوين CSP افتراضي لـ script-src * 'unsafe-inline' 'unsafe-eval' blob: ; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;.

وضع صارم

يعمل تبديل Strict CSP عَلَى إنشاء CSP الذي لا يتضمن في الغالب أحرف البدل أو التوجيهات غير الآمنة، مثل unsafe-inline. عند تشغيل Strict CSP، تصبح التوجيهات السابقة التوجيهات التالية المفصلة في هذا القسم. <platform> يعني تدوين أن مجالات النظام الأساسي يتم توفيرها كما هو مطلوب من قبل المنتج. قد تتغير المجالات في هذا القسم بمرور الوقت مع نمو المنتج.

التوجيه القيمة الافتراضية (المستندة إلى النموذج) القيمة الافتراضية (لوحة) قابل للتخصيص
script-src 'self' blob: <platform>' 'self' <platform>' نعم
worker-src 'self' blob: 'self' blob: لا
style-src 'self' 'unsafe-inline' <platform> 'self' 'unsafe-inline' <platform> نعم
font-src 'self' data: <platform> 'self' data: <platform> نعم
frame-ancestors 'self' https://*.powerapps.com 'self' https://*.powerapps.com نعم
img-src 'self' blob: data: <platform> 'self' data: <platform> نعم
connect-src 'self' blob: data: wss: <platform> 'self' blob: <platform> نعم
frame-src 'self' blob: <platform> 'self' <platform> نعم
base-uri 'none' ‏‫غير متوفر‬ لا
form-action <platform> ‏‫غير متوفر‬ نعم
default-src 'self' 'self' لا

المتطلبات الأساسية

بالنسبة لتطبيقات Dynamics 365 Customer Engagement والتطبيقات الأخرى المستندة إلى نموذج، لا يتوفر CSP إلا في بيئات الإنترنت وفي المؤسسات التي لديها الإصدار 9.1 من Dynamics 365 Customer Engagement (on-premises) أو إصدار أحدث.

تكوين سياسة أمان المحتوى (CSP)

يمكنك تبديل CSP وتكوينه من خلال مركز مسؤولي Power Platform. من المهم تمكين بيئة التطوير/الاختبار أولاً لأن تمكين 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.comو و https://www.bar.comولكن ليس في أصول أخرى. استخدم الزر إضافة لإضافة الإدخالات إلى القائمة وأيقونة الحذف لإزالتها.

تعيين توجيهات CSP مخصصة.

التكوينات الشائعة

للتكامل مع Microsoft Teams باستخدام تطبيق Dynamics 365، أضف ما يلي إلى frame-ancestors:

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

بالنسبة لـ Dynamics 365 App for Outlook، أضف التالي إلى frame-ancestors:

  • أصل الصفحة الرئيسية لتطبيق ويب في Outlook
  • https://outlook.office.com
  • https://outlook.office365.com

لتضمين Power Apps في تقارير Power BI، أضف ما يلي frame-ancestors:

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

اعتبارات هامة

يؤدي إيقاف تشغيل التوجيه الافتراضي وحفظه بقائمة فارغة إلى إيقاف تشغيل التوجيه بشكل تام ولا يرسله كجزء من رأس استجابة CSP.

أمثلة على تكوين CSP

فيما يلي مثالان لتكوينات CSP.

مثال 1 - تم إيقاف إعداد التقارير

مثال CSP 1، يستند إلى النموذج

مثال CSP 1، لوحة

في المثال:

  • تم إيقاف تشغيل إعداد التقارير.
  • يتم تمكين فرض تطبيق يستند إلى النموذج.
    • frame-ancestors تم تخصيص إلى https://www.contoso.com و https://www.fabrikam.com.
  • تم تعطيل فرض اللوحة.

العناوين الفعالة هي:

  • التطبيقات المستندة إلى النموذج: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors https://www.contoso.com https://www.fabrikam.com;
  • تطبيقات Canvas: لا يتم إرسال رأس CSP.

مثال 2 - تم تشغيل إعداد التقارير

مثال CSP 2، يستند إلى النموذج

مثال CSP 2، لوحة

في المثال:

  • تم تشغيل إعداد التقارير.
    • تم تعيين نقطة نهاية التقرير إلى https://contoso.com/reporting-endpoint
  • يتم تمكين فرض تطبيق يستند إلى النموذج.
    • تم الاحتفاظ بـ frame-ancestors كافتراضي
  • تم تعطيل فرض اللوحة.
    • تم تخصيص frame-ancestors إلى https://www.contoso.com

قيم CSP الفعالة هي:

  • التطبيقات المستندة إلى النموذج: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob:; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com; report-uri https://contoso.com/reporting-endpoint;
  • تطبيقات اللوحة: 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;

تعديل إعدادات المؤسسة مباشرةً

يمكنك تكوين CSP دون استخدام واجهة المستخدم عن طريق تعديل إعدادات المؤسسة هذه مباشرةً:

  • IsContentSecurityPolicyEnabled يتحكم فيما إذا تم إرسال رأس سياسة أمان المحتوى في التطبيقات التي تستند إلى النموذج.

  • يتحكم ContentSecurityPolicyConfiguration في قيمة جزء frame-ancestors (كما رأينا سابقا، يتم تعيينه إلى 'self' إذا 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 Content-Security-Policy (CSP) frame-ancestors الأصول الصالحة التي قد تضمن صفحة باستخدام <frame>, <iframe>, <object>, <embed>, or <applet>.
  • IsContentSecurityPolicyEnabledForCanvas يتحكم فيما إذا تم إرسال رأس سياسة أمان المحتوى في تطبيقات اللوحة.

  • ContentSecurityPolicyConfigurationForCanvas يتحكم في نهج اللوحة باستخدام نفس العملية الموضحة في ContentSecurityPolicyConfiguration.

  • ContentSecurityPolicyReportUri يتحكم فيما إذا كان يجب استخدام إعداد التقارير. يستخدم هذا الإعداد كل من التطبيقات التي تستند إلى النموذج وتطبيقات اللوحة. ترسل سلسلة صالحة تقارير الانتهاكات إلى نقطة النهاية المحددة، باستخدام وضع التقرير فقط إذا تم إيقاف تشغيل IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas. تعطل سلسلة فارغة إعداد التقارير. لمزيد من المعلومات حول ، راجع وثائق إعداد التقارير.

تكوين CSP بدون واجهة المستخدم

قد يرغب المسؤولون في تكوين CSP باستخدام البرامج النصية لتعديل الإعدادات مباشرة، تحديدًا في البيئات غير الموجودة في مركز مسؤولي Power Platform، مثل التكوينات المحلية.

تمكين CSP بدون واجهة مستخدم

اتبع هذه الخطوات لتمكين 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!')
}

تعطيل CSP بدون واجهة مستخدم

اتبع هذه الخطوات لتعطيل 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!')
}