Тонкости проверки прав доступа

18.11.25

Администрирование - Роли и права

Когда возникает ошибка, связанная с правами доступа, не всегда понятно, куда копать… И решение проблемы может быть достаточно долгим. Знание некоторых нюансов работы платформы может помочь в этом вопросе

Итак, поехали…

Начать хочу с ошибок, связанных нарушением доступа на уровне записей. Наш любимый rls. Ошибка, которая возникает в таких случаях, всем хорошо знакома:

 

 

Ошибка возникает в том случае, если в запросе выбираются данные, которые пользователю запрещены на уровне записей и в запросе не указано ключевое слово РАЗРЕШЕННЫЕ.

Если ключевое слово РАЗРЕШЕННЫЕ указать, то запрещенных записей в результате запроса не будет. А если основная таблица выборки разрешена, а запрещено одно из вложенных полей, это поле будет показано в выборки как битая ссылка, а все реквизиты этого поля будут иметь значение NULL.

Давайте посмотрим, что же меняется в запросе к серверу СУБД, в зависимости от наличия или отсутствия инструкции РАЗРЕШЕННЫЕ?

А меняется следующее:

Если ключевого слова РАЗРЕШЕННЫЕ нет в запросе, в выборке будет присутствовать дополнительное поле (первое по порядку). в этом поле, собственно, и выполняются все проверки доступа на уровне записей. Поле будет приблизительно такого вида:

CASE WHEN (EXISTS(SELECT 0x01 AS Q_001_F_000_

FROM dbo._Reference250X1 T4

INNER JOIN dbo._Reference165 T5

ON (T4._Fld59163 = ?) AND EXISTS(SELECT 0x01 AS Q_004_F_000_

FROM dbo._InfoRg47609X1 T6

WHERE ((T6._Fld2589 = ?)) AND ((T6._Fld47610_TYPE = 0x08 AND T6._Fld47610_RTRef = 0x000000FA AND T6._Fld47610_RRRef = T4._IDRRef) AND (T6._Fld47611RRef = T5._IDRRef))) AND T5._IDRRef IN

(SELECT T8._Reference165_IDRRef AS ACCESS_GROUPRRef

FROM dbo._Reference165_VT56822 T8

INNER JOIN dbo._InfoRg46624 T9

ON (T9._Fld46626_TYPE = 0x08 AND T9._Fld46626_RTRef = 0x000001F8 AND T9._Fld46626_RRRef = ?) AND (T9._Fld46625_TYPE = T8._Fld56824_TYPE AND T9._Fld46625_RTRef = T8._Fld56824_RTRef AND T9._Fld46625_RRRef = T8._Fld56824_RRRef)

WHERE ((T8._Fld2589 = ?)) AND (T9._Fld2589 = ?))

WHERE ((T5._Fld2589 = ?)) AND ((1=1) AND (CASE WHEN EXISTS(SELECT 0x01 AS Q_002_F_000_

FROM dbo._InfoRg40111 T10

WHERE ((T10._Fld2589 = ?)) AND ((T10._Fld40112RRef = T5._IDRRef) AND (T10._Fld40113_TYPE = 0x08 AND T10._Fld40113_RTRef = 0x0000018D AND T10._Fld40113_RRRef = T1._Fld20869RRef))) THEN 0x01 ELSE 0x00 END = CASE WHEN EXISTS(SELECT 0x01 AS Q_003_F_000_

FROM dbo._InfoRg40118 T11

WHERE ((T11._Fld2589 = ?)) AND ((T11._Fld40119RRef = T5._IDRRef) AND T11._Fld40120_TYPE = 0x08 AND T11._Fld40120_RTRef = 0x0000018D AND (T11._Fld40121 = 0x00))) THEN 0x01 ELSE 0x00 END)))) = 0x01 THEN 0x01 ELSE 0x00 END

Если в нем разобраться, то будет видно, что это фрагмент кода из шаблона ограничений доступа на уровне записей ПоЗначениям. И это один из самых простых видов ограничений всего лишь по одному виду доступа и по одному объекту )). Теперь становиться понятно, почему запросы с rls так тормозят. 

И так, если доступ к записи разрешен, в первом поле выборки возвращается значение ИСТИНА, если не разрешен, возвращается ЛОЖЬ. После этого платформа проверяет выборку на наличие записей со значением ЛОЖЬ в первом поле. И если такие записи есть, выдает наше любимое сообщение об ошибке.

А вот если ключевое слово РАЗРЕШЕННЫЕ в запросе есть, он строиться принципиально по-другому. Все проверки выполняются не в дополнительном поле, а в секции ГДЕ. Соответственно, если проверка не проходит, запись попросту не будет возвращена, и ни каких ошибок.  

Теперь посмотрим, что меняется в запросе, если доступ на уровне записей выполняется еще и для вложенного объекта. Например, выборка из регистра «Остатки по складам». В дополнении к самому регистру есть ограничения на уровне записей к номенклатуре. Отметим, что выборке должен присутствовать какой-либо реквизит номенклатуры. Это важно, так как если в выборке присутствует только ссылка на номенклатуру, никаких дополнительных проверок выполнено не будет. Ссылка вернется запросом. А вот получение основного представления ссылки получено не будет, так как для его получения будет выполнен отдельный запрос к СУБД с дополнительной проверкой. В результате мы увидим ту самую битую ссылку.

 

Что поменяется в запросе к серверу СУБД?

Без инструкции РАЗРЕШЕННЫЕ в запросе будет дополнительная таблица, соединенная с основной левым соединением. Во второй таблице также будет дополнительное поле (ИСТИНА / ЛОЖЬ), в котором будут выполняться проверки rls уже для справочника Номенклатура. Поле это будет иметь специальный алиас: SDBL_RLS_SIGNAL_. Далее значение этого поля добавляется к первому полю основной выборки:

…AND ISNULL(T2.SDBL_RLS_SIGNAL_,0x01)

В результате мы получаем следующее поведение:

Если доступ на уровне записей к основной таблице есть, а к одному из полей нет, и в выборке есть вложенный реквизит этого поля, будет ошибка ограничения прав на уровне записей, так как в выборке будут присутствовать строки с значением первого поля = ЛОЖЬ. Если в выборке присутствует только ссылка на недоступный объект, дополнительной таблицы в запросе не будет и проверки прав на нее тоже не будет. Следовательно, не будет и ошибки, а вместо представления объекта будет показана битая ссылка.

В случае, когда в запросе есть инструкция РАЗРЕШЕННЫЕ, в запросе к СУБД также будет дополнительная таблица с левым соединением, только проверки теперь будут в секции ГДЕ этой таблицы. Соответственно, если прав к записям таблицы нет, она их просто не вернет и вложенное поле будет иметь значение NULL.

Исходя из вышеописанного можно сделать вывод, что ключевое слова РАЗРЕШЕННЫЕ влияет на поведение запроса только в случае использования rls.

Так ли это?

 

Давайте экспериментировать дальше.

Представим, что у пользователя есть доступ к основной таблице выборки и нет к вложенному объекту. Нет доступа не на уровне записей, а на уровне ролей, то есть ко всем записям таблицы.

Сформируем следующий простой запрос, без инструкции РАЗРЕШЕННЫЕ:

ВЫБРАТЬ ПЕРВЫЕ 1

ПервичныйДокумент.эу_ВПД КАК ВПД,

ПервичныйДокумент.эу_ВПД.Номер КАК ВПДНомер,

ПервичныйДокумент.Ссылка КАК Ссылка

ИЗ Документ.ПервичныйДокумент КАК ПервичныйДокумент

ГДЕ ПервичныйДокумент.Номер = &Номер

При условии, что у пользователя нет прав на уровне ролей к документу эу_ВПД, в результате мы получим ошибку:

 

 

Все очевидно и понятно. Такое же сообщение будет выведено, если запросить выборку из недоступной таблицы явно, вне зависимости от опции РАЗРЕШЕННЫЕ.

Теперь добавим инструкцию РАЗРЕШЕННЫЕ в запрос.

Опять ошибка, но сообщение следующее:

 

 

[ОшибкаВоВремяВыполненияВстроенногоЯзыка]

по причине:

{(3, 41)}: Поле не найдено "ПервичныйДокумент.эу_ВПД.Номер"

ПервичныйДокумент.эу_ВПД.Номер КАК ВПДНомер

 

Теперь изменим обращение к полю Номер используя конструкцию ВЫРАЗИТЬ

ВЫРАЗИТЬ(ПервичныйДокумент.эу_ВПД КАК Документ. эу_ВПД).Номер

Выполним запрос без конструкции РАЗРЕШЕННЫЕ.

И получаем… до боли знакомое сообщение об ошибке:

 

 

Что такое?

У нас ведь ограничение на уровне ролей, а не записей!

Ладно, давайте добавим инструкцию РАЗРЕШЕННЫЕ.

И-и-и. УСПЕХ!

Сообщения об ошибки нет. Данные возвращены. Поле ВПД представлено битой ссылкой, а поле ВПДНомер – значение NULL. Так и предполагалось.

 

Давайте разбираться.

Без конструкции ВЫРАЗИТЬ система явно показывает, что не так. В первом случае явно пишет, что к такой-то таблице нет доступа. Во-втором указывает на отсутствие реквизита объекта. Важно отметить, что в обоих случаях это проверки платформы до формирования запроса к серверу СУБД.

 

Почему поведение отличается?

Трудно сказать наверняка. Возможно, если платформа использует РАЗРЕШЕННЫЕ и встречает в запросе недоступный для пользователя объект, заменяет его на NULL. Соответственно, у поля NULL не находит нужного реквизита. В любом случае, в обоих вариантах запрос к серверу базы данных не формируется. По событию DBMSSQL в технологическом журнале вы ничего не найдете.

Если используется конструкция ВЫРАЗИТЬ, система при предварительном анализе запроса явных проблем не находит и формирует запрос к СУБД.

Без инструкции РАЗРЕШЕННЫЕ, на СУБД выполняется запрос такого вида:

SELECT TOP 1

ISNULL(T2.SDBL_RLS_SIGNAL_,0x01),

T1._Fld92959RRef,

T2.Number_,

T1._IDRRef

FROM dbo._Document1116 T1

LEFT OUTER JOIN (SELECT

(0x00) AS SDBL_RLS_SIGNAL_,

T3._Number AS Number_,

T3._IDRRef AS IDRRef,

T3._Fld2589 AS Fld2589_

FROM dbo._Document74610 T3

WHERE (T3._Fld2589 = ?)) T2

ON T1._Fld92959RRef = T2.IDRRef

WHERE ((T1._Fld2589 = ?)) AND ((T1._Number = ?))

Обратите внимание на поле: SDBL_RLS_SIGNAL_. Как видим, что поведение аналогично тому, если бы использовалось rls. Выбираются все данные и помечаются строки, в которых присутствуют запрещенные записи. В нашем случае, это все записи, в которых есть связанный объект эу_ВПД. По этой причине и сообщение об ошибке соответствующее.  

С инструкцией РАЗРЕШЕННЫЕ, запрос меняется на следующий:

SELECT TOP 1

T1._Fld92959RRef,

T2._Number,

T1._IDRRef

FROM dbo._Document1116 T1

LEFT OUTER JOIN dbo._Document74610 T2

ON ((T1._Fld92959RRef = T2._IDRRef) AND (T2._Fld2589 = ?)) AND (0x00) = 0x01

WHERE ((T1._Fld2589 = ?)) AND ((T1._Number = ?))

Обратите внимание на выражение (0x00) = 0x01. Записи дополнительной таблицы явно отсекаются. Из-за этого получаем закономерное NULL при выводе номера и никаких ошибок.

 

Какие выводы можно сделать из вышесказанного

  1. Сообщения об ошибке с явным указанием таблиц или полей свидетельствует о том, что сработал предварительный анализ запроса платформой и запрос еще не был отправлен на сервер СУБД.
  2. Конструкция РАЗРЕШЕННЫЕ в запросах, влияет на результат не только в тех случаях, когда используется rls. Соответственно сообщение «У пользователя недостаточно прав на исполнение операции над базой данных» не всегда свидетельствует об отсутствии прав на уровне записей.
  3. Совместное использование конструкций РАЗРЕШЕННЫЕ и ВЫРАЗИТЬ позволяет избежать ошибок при обращении к вложенным полям объекта, недоступного для пользователя на уровне ролей.

  

Маленький бонус

В технологическом журнале есть одно событие - QERR.

Для его включения, в файле logcfg.xml можно сделать следующую настройку:

 <log location="D:\1c\ERP" history="2">
      <event>
          <eq property="name" value="QERR"/>
          <eq property="p:processName" value="ERP "/>
      </event>                           
      <property name="all"/>
 </log>

Событие вызывается при любой из вышеприведенных ошибок с правами доступа. Даже в тех случаях, когда выполнен только предварительный анализ запроса платформой и он еще не был отправлен на сервер СУБД.

В этом событии в поле Query выводится текст запроса в таком виде, в каком он был задан в конфигураторе.

Напомню, события DBMSSQL и SDBL возвращают текст запроса, преобразованный к формату базы данных.

Также в событии QERR в поле Context выводится контекст возникновения ошибки.

 

Удачи Вам в расследовании ошибок с правами доступа!

 

А с какими не очевидными ошибками системы прав доступа сталкивались Вы?

Вступайте в нашу телеграмм-группу Инфостарт

Права доступа rls БСП

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    226367    1228    415    

1074

Инструменты администратора БД Инструментарий разработчика Роли и права Программист 1С v8.3 1C:Бухгалтерия Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

16000 руб.

10.11.2023    20755    86    42    

95

Зарплата Роли и права Системный администратор Бухгалтер 1С v8.3 Бухгалтерский учет Управление правами 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Комплексная автоматизация 2.х Молдова Россия Казахстан Бухгалтерский учет Платные (руб)

Расширение позволяет максимально полно ограничить доступ пользователей к данным по заработной плате, а именно закрывает доступ к документам начисления и выплаты заработной платы, не позволяет просматривать бухгалтерские отчеты по счету учета зарплаты а также убирает зарплатные проводки из журнала проводок. Расширение запрещает просматривать платежные документы на выплату зарплаты, так же не доступны регламентные отчеты в ПФР и ИФНС. Расширение предлагает готовые настроенные профили "Бухгалтер без зарплаты", "Только просмотр без зарплаты".

5940 руб.

27.05.2021    48314    382    119    

294

Инструменты администратора БД Роли и права Системный администратор Программист Пользователь 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 17.06.2025, версия 1.3

20400 руб.

06.12.2023    18578    68    10    

102

Логистика, склад и ТМЦ Роли и права Программист Бухгалтер Пользователь 1С v8.3 Бухгалтерский учет Управление правами 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Расширение для 1С:Бухгалтерия 3.0, которое позволяет использовать отдельные роли для доступа к складским документам, для доступа к документам раздела "Производство" и для доступа к документам раздела "Покупки".

5000 руб.

21.05.2019    1699090    587    195    

143

Ценообразование, анализ цен Роли и права Системный администратор 1С v8.3 Управление правами 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Расширение возможностей программы 1С:УНФ 1.6 и 3.0. Функционал расширения - разграничение всевозможных прав пользователей и контроль при совершении различных действий.

5016 руб.

23.02.2018    64373    177    264    

168

Роли и права Системный администратор Программист 1С v8.3 Управляемые формы Управление правами 1C:Бухгалтерия Платные (руб)

Получение необходимой информации по правам доступа в разрезе групп доступа, профилей групп доступа, пользователей / групп пользователей, объектов конфигурации и ролей. Легко можно настроить состав и порядок вывода информации по правам, настроить необходимые фильтры и получить более детальную расшифровку по группировкам отчета.

5000 руб.

16.11.2015    52222    97    46    

159
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. RustIG 1931 18.11.25 10:55 Сейчас в теме
А с какими не очевидными ошибками системы прав доступа сталкивались Вы?

механизм ЭДО - все процедуры в фоновом режиме через механизм длительных операций - Журнал регистрации плохо фиксирует любые ошибки (в том числе, нарушение прав доступа) - выдает ошибку в модуле длительной операции, а какой процесс в него попал неизвестно.... Естественно, через отладчик в этот модуль не попасть, а если отлаживать не в фоновом режиме (в ручном режиме), то в модуль длительных сеансов не попасть.... если повезет всплывет ошибка...
2. RustIG 1931 18.11.25 11:09 Сейчас в теме
а как такие ограничения отлаживать? запускать консоль запросов под пользователем с ограниченными правами? и проверять запросы в окне консоли? получится ли так? или только через отладчик и конфигуратор? или и вовсе только через технологический журнал?
3. ids79 8731 18.11.25 11:46 Сейчас в теме
(2) В этом случае наверно только через технологический журнал
Для отправки сообщения требуется регистрация/авторизация