سياسة أمان المحتوى
إشعار
إن مركز مسؤولي Power Platformالجديد والمحسن موجود الآن في إصدار أولي للاستخدام العام! لقد صممنا مركز الإدارة الجديد ليكون أسهل في الاستخدام، مع التنقل الموجه نحو المهام الذي يساعدك على تحقيق نتائج محددة بشكل أسرع. سننشر وثائق جديدة ومحدثة مع انتقال مركز مسؤولي Power Platform الجديد إلى التوفر العام.
يتم حاليًا دعم سياسة أمان المحتوى (CSP) في التطبيقات التي تستند إلى النموذج وتطبيقات اللوحة Power Apps. يمكن للمسؤولين التحكم في إرسال رأس CSP وما يحتويه، إلى حد ما. هذا الإعداد على مستوى البيئة، ما يعني أنه سيتم تطبيقه على جميع التطبيقات في البيئة بمجرد تشغيله.
إشعار
لا تنطبق سياسة أمان المحتوى إلا على البيئات التي Dataverse تستخدم.
يتحكم كل مكون في قيمة رأس CSP في الأصول التي يمكن تنزيلها والموضحة بشكل أكثر تفصيلاً على شبكة مطور Mozilla (MDN). القيم الافتراضية هي كما يلي:
التوجيه | القيمة الافتراضية | قابل للتخصيص |
---|---|---|
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 Customer Engagement والتطبيقات الأخرى المستندة إلى نموذج، لا يتوفر CSP إلا في بيئات الإنترنت وفي المؤسسات التي لديها الإصدار 9.1 من Dynamics 365 Customer Engagement (on-premises) أو إصدار أحدث.
تكوين CSP
يمكن تبديل CSP وتكوينه عبر مركز مسؤولي Power Platform. من الضروري تمكين بيئة تطوير/اختبار أولاً نظرًا لأن تمكين CSP قد يبدأ في حظر السيناريوهات في حالة انتهاك السياسة. ونحن ندعم أيضًا "وضع التقرير فقط" للسماح بتسهيل زيادة الإنتاج.
لتكوين CSP، انتقل إلى مركز مسؤولي Power Platform ->البيئات ->الإعدادات ->الخصوصية + الأمان. الصورة التالية توضح الحالة الافتراضية للإعدادات:
جارٍ إرسال التقرير
يتحكم مفتاح تبديل "تمكين إعداد التقارير" فيما إذا كانت التطبيقات التي تستند إلى النموذج وتطبيقات اللوحة ترسل تقارير عن الانتهاك. يتطلب تمكين إعداد التقارير وجود نقطة نهاية يلزم تحديدها. يتم إرسال تقارير الانتهاك إلى نقطة النهاية هذه بغض النظر عما إذا تم فرض CSP أم لا (باستخدام وضع التقرير فقط إذا لم يتم فرض CSP). لمزيد من المعلومات حول ، راجع وثائق إعداد التقارير.
الفرض
يتم التحكم في فرض CSP بشكل مستقل للتطبيقات التي تستند إلى النموذج وتطبيقات اللوحة لتوفير تحكم دقيق في السياسات. استخدم العرض المحوري للتطبيقات التي تستند إلى النموذج/تطبيقات اللوحة لتعديل نوع التطبيق المقصود.
يعمل مفتاح التبديل "فرض سياسة أمان المحتوى" على تشغيل السياسة الافتراضية للتنفيذ لنوع التطبيق المحدد. يؤدي تشغيل مفتاح التبديل هذا إلى تغيير سلوك التطبيقات في هذه البيئة بهدف الالتزام بالسياسة. وبالتالي، سيكون سير عمل التمكين المقترح:
- فرض على بيئة تطوير/اختبار.
- تمكين وضع التقرير فقط في الإنتاج.
- فرض في الإنتاج بمجرد عدم وجود انتهاكات.
تكوين التوجيهات
يتيح لك هذا القسم التحكم في التوجيهات الفردية داخل السياسة. وفي الوقت الحالي، يمكن تخصيص frame-ancestors
فقط.
يؤدي ترك التوجيه الافتراضي قيد التشغيل إلى استخدام القيمة الافتراضية المحددة في الجدول الموضح سابقًا في هذه المقالة. يتيح إيقاف تشغيل التبديل للمسؤولين تحديد قيم مخصصة للتوجيه وإلحاقها بالقيمة الافتراضية. المثال أدناه يحدد قيمًا مخصصة لـ frame-ancestors
. سيتم تعيين التوجيه إلى frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com
في هذا المثال، ما يعني أنه يمكن استضافة التبطيق في الأصل نفسه، https://*.powerapps.com
, https://www.foo.com
و https://www.bar.com
، ولكن ليس في أصول أخرى. استخدم الزر "إضافة" لإضافة الإدخالات إلى القائمة وأيقونة الحذف لإزالتها.
التكوينات الشائعة
للتكامل مع 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:
المثال 1
في المثال:
- تم إيقاف تشغيل إعداد التقارير.
- يتم تمكين فرض تطبيق يستند إلى النموذج.
- تم تخصيص
frame-ancestors
إلىhttps://www.foo.com
وhttps://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
في المثال:
- تم تشغيل إعداد التقارير.
- تم تعيين نقطة نهاية التقرير إلى
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 بدون استخدام واجهة المستخدم من خلال تعديل إعدادات المؤسسة التالية مباشرة:
IsContentSecurityPolicyEnabled يتحكم فيما إذا تم إرسال رأس Content-Security-Policy في التطبيقات التي تستند إلى النموذج.
ContentSecurityPolicyConfiguration يتحكم في قيمة جزء أسلاف الإطار (كما هو موضح أعلاه، تم ضبطه على
'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>
.
- (من MDN) يحدد توجيه HTTP Content-Security-Policy (CSP) frame-ancestors الأصول الصالحة التي قد تضمن صفحة باستخدام
IsContentSecurityPolicyEnabledForCanvas يتحكم فيما إذا تم إرسال رأس Content-Security-Policy في تطبيقات اللوحة.
ContentSecurityPolicyConfigurationForCanvas يتحكم في سياسة تطبيق اللوحة باستخدام العملية نفسها التي تم وصفها في
ContentSecurityPolicyConfiguration
أعلاه.ContentSecurityPolicyReportUri يتحكم فيما إذا كان يجب استخدام إعداد التقارير. يستخدم هذا الإعداد كل من التطبيقات التي تستند إلى النموذج وتطبيقات اللوحة. ترسل سلسلة صالحة تقارير الانتهاكات إلى نقطة النهاية المحددة، باستخدام وضع التقرير فقط إذا تم إيقاف تشغيل
IsContentSecurityPolicyEnabled
/IsContentSecurityPolicyEnabledForCanvas
. تعطل سلسلة فارغة إعداد التقارير. لمزيد من المعلومات حول ، راجع وثائق إعداد التقارير.
تكوين CSP بدون واجهة المستخدم
قد يرغب المسؤولون في تكوين CSP باستخدام البرامج النصية لتعديل الإعدادات مباشرة، تحديدًا في البيئات غير الموجودة في مركز مسؤولي Power Platform، مثل التكوينات المحلية.
تمكين 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، الصقها في وحدة التحكم:
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!')
}