Политика безопасности содержимого
политика безопасности контента (CSP) в настоящее время поддерживается в режимах на основе моделей и Canvas Power Apps. Администраторы могут контролировать, отправляется ли заголовок CSP и, в некоторой степени, что он содержит. Настройки находятся на уровне среды, то есть после включения они будут применены ко всем приложениям в среде.
Каждый компонент значения заголовка CSP управляет активами, которые могут быть загружены, и более подробно описан в Mozilla Developer Network (MDN). Значения по умолчанию приведены ниже:
Директива | Значение по умолчанию | Настраивается |
---|---|---|
скрипт-src | * 'unsafe-inline' 'unsafe-eval' |
Нет |
работник-src | 'self' blob: |
Нет |
стиль-src | * 'unsafe-inline' |
Нет |
источник-шрифта | * data: |
нет |
кадр-предки | '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 для взаимодействия с клиентами и других приложений на основе моделей CSP доступен только в онлайн-средах и в организациях с Dynamics 365 для взаимодействия с клиентами (локальный) версии 9.1 или более поздней.
Настройка 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 Web App
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 управляет значением части 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>
или<applet>
.
- (Из MDN) Директива HTTP Content-Security-Policy (CSP) frame-ancestors указывает действительные родительские элементы, которые могут встраивать страницу, используя
IsContentSecurityPolicyEnabledForCanvas контролирует, отправляется ли заголовок Content-Security-Policy в приложениях Canvas.
ContentSecurityPolicyConfigurationForCanvas управляет политикой для холста, используя тот же процесс, который описан
ContentSecurityPolicyConfiguration
выше.ContentSecurityPolicyReportUri контролирует, следует ли использовать отчетность. Этот параметр используется как приложениями на основе модели, так и приложениями на основе холста. Действительная строка отправляет отчеты о нарушениях на указанную конечную точку, используя режим только отчетов, если
IsContentSecurityPolicyEnabled
/IsContentSecurityPolicyEnabledForCanvas
выключен. Пустая строка отключает отчетность. Дополнительные сведения см. в документации по отчетности.
Настройка 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, вставьте в консоль:
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!')
}