При разработке и интеграции собственных HTTP-сервисов в типовые конфигурации 1С (такие как "Управление торговлей 11", "ERP Управление предприятием" или "Комплексная автоматизация") через механизм расширений разработчики часто сталкиваются с неприятной проблемой. Все настройки выполнены корректно: HTTP-сервис опубликован на веб-сервере, в файле default.vrd прописаны пути, создана специальная роль с правами на "Использование" сервиса, и эта роль назначена пользователю. Однако при попытке отправить запрос система возвращает ошибку "HTTP 403 Forbidden" (Недостаточно прав для использования ресурса с данным HTTP-методом).
В этой статье мы подробно разберем, почему возникает данная ошибка, как механизмы Библиотеки стандартных подсистем (БСП) влияют на разграничение прав в расширениях, и рассмотрим три практических способа решения этой проблемы — от быстрого программного обхода до архитектурно правильной настройки прав.
Для начала проанализируем поведение системы. В Журнале регистрации мы можем увидеть, что сеанс успешно создается и проходит аутентификацию под нужным пользователем (например, под учетной записью администратора), но до выполнения кода самого обработчика HTTP-сервиса дело не доходит. Платформа сразу отвергает запрос с ошибкой 403.
Причина кроется в особенностях работы Библиотеки стандартных подсистем (БСП), на базе которой построены практически все современные конфигурации 1С. В БСП встроен жесткий механизм контроля и оптимизации состава ролей пользователей. Периодически (при обновлении информационной базы, выполнении регламентных заданий или принудительном вызове обновления прав) система полностью пересчитывает роли всех активных пользователей:
ПолныеПрава и АдминистраторСистемы.Ниже мы рассмотрим три способа решения этой проблемы, начиная с простейшего обхода и заканчивая наиболее надежными и правильными с точки зрения стандартов разработки "1С".
Если вам необходимо срочно предоставить доступ к сервису конкретному пользователю, можно назначить ему роль из расширения программно в обход интерфейса ограничений БСП. Для этого мы можем временно использовать привилегированный режим и напрямую добавить роль в объект ПользовательИнформационнойБазы.
Рассмотрим пример кода, который выполняет эту операцию:
УстановитьПривилегированныйРежим(Истина);
ИмяПользователя = "admin3"; // Имя вашего администратора
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя);
Если ПользовательИБ <> Неопределено Тогда
// Получаем метаданные роли из нашего расширения
РольСервиса = Метаданные.Роли.ЦЗПрава_HTTP_Сервисы;
// Проверяем, не добавлена ли роль ранее
Если Не ПользовательИБ.Роли.Содержит(РольСервиса) Тогда
ПользовательИБ.Роли.Добавить(РольСервиса);
ПользовательИБ.Записать();
КонецЕсли;
КонецЕсли;
УстановитьПривилегированныйРежим(Ложь);
Важное предупреждение: Данный метод является временным "костылем". При первом же обновлении конфигурации, запуске фонового обновления прав БСП или изменении настроек пользователя в режиме предприятия, БСП снова пересчитает роли и удалит добавленную вручную роль расширения. Данный способ подходит только для быстрой отладки.
Чтобы права доступа не "слетали" при проверках БСП, мы можем пойти наиболее простым и надежным путем, соответствующим стандартам разработки 1С. Вместо создания новой роли в расширении и попыток назначить её администратору, мы расширим права уже существующей у администратора роли ПолныеПрава.
Разберем этот процесс по шагам:
ПолныеПрава (или АдминистраторСистемы), нажмите по ней правой кнопкой мыши и выберите пункт "Добавить в расширение".ПолныеПрава.Почему это работает? Администратор системы по умолчанию обладает ролью ПолныеПрава. БСП никогда не удаляет эту роль у администратора. Платформа 1С объединяет права основной конфигурации и расширения для одноименных ролей. Таким образом, администратор автоматически получает право на использование вашего HTTP-сервиса, а механизмы безопасности БСП не фиксируют никаких "лишних" ролей у пользователя.
Если логика безопасности требует, чтобы доступ к HTTP-сервису регулировался строго отдельной ролью, и вы хотите назначать её пользователям через стандартные профили групп доступа, необходимо "объяснить" БСП, что данная роль из расширения является легитимной.
Для этого выполните следующие действия:
ПользователиПереопределяемый.ПриОпределенииНазначенияРолей(НазначениеРолей).
&После("ПриОпределенииНазначенияРолей")
Процедура Расш_ПриОпределенииНазначенияРолей(НазначениеРолей)
// Регистрируем роль расширения как доступную для администраторов и системных пользователей
НазначениеРолей.ТолькоДляПользователейСистемы.Добавить(
Метаданные.Роли.ЦЗПрава_HTTP_Сервисы.Имя
);
КонецПроцедуры
После внесения этих изменений и запуска обновления информационной базы (параметр запуска /c ЗапуститьОбновлениеИнформационнойБазы) БСП примет вашу роль как разрешенную и перестанет принудительно удалять её у системных учетных записей.
При работе с правами в расширениях важно знать критическую особенность поведения платформы "1С:Предприятие 8":
Если в вашем расширении вообще нет ни одной роли, то платформа автоматически предоставляет доступ ко всем добавленным в расширение объектам (включая HTTP-сервисы) абсолютно всем пользователям информационной базы, у которых есть базовые права на запуск системы. Но как только вы создаете в расширении хотя бы одну собственную роль, поведение платформы кардинально меняется: доступ ко всем новым объектам этого расширения полностью блокируется для всех пользователей, пока им не будет явно назначена роль из этого расширения, дающая соответствующие права.
Напоследок убедимся, что ваш сервис корректно опубликован в файле настроек веб-сервера default.vrd. При публикации сервисов из расширений важно соблюдать правила адресации и именования.
Рекомендуется использовать параметр publishExtensionsByDefault="true" в узле <httpServices>. Это позволит платформе автоматически публиковать все HTTP-сервисы из всех подключенных расширений без необходимости их ручного описания. Пример корректного файла конфигурации выглядит так:
<httpServices publishExtensionsByDefault="true">
<!-- Если требуется переопределить параметры конкретного сервиса из расширения -->
<service name="ИмяРасширения_ИмяСервиса" rootUrl="RecalcTotals" enable="true"/>
</httpServices>
Обратите внимание, что имя сервиса в файле публикации должно состоять из имени расширения и имени самого сервиса, разделенных символом подчеркивания, если в свойствах сервиса не задано иное.
Используя предложенные нами архитектурные подходы (в особенности Способ 2 с расширением стандартной роли ПолныеПрава), вы навсегда избавитесь от проблемы "слетающих" прав и обеспечите стабильную и безопасную работу ваших интеграционных HTTP-сервисов в среде 1С.