Каталог решений - Производительный режим работы RLS

Производительный режим работы RLS

Производительный режим работы RLS

В наличии

Функционал подсистемы УправлениеДоступом позволяет работать с RLS в двух режимах: стандартном и производительном. Каждый из режимов имеет свои преимущества и недостатки относительно другого. Основные из них будут рассмотрены в данном материале.

Категория:

Описание

Оглавление

Некоторые типы ограничений

Примеры возможных ограничений

Отличительная особенность производительного режима RLS

Несколько конкретных примеров внедрения

 

Для гибкой настройки прав пользователей в конфигурациях на базе БСП (подсистема УправлениеДоступом) реализован механизм настройки доступа на уровне записей (RLS). Этот механизм позволяет ограничивать доступ не только по видам объектов (для конкретных справочников, документов…), но и по данным в этих объектах (т.е., например, ограничить список документов только по одной организации или по конкретному менеджеру).

Функционал подсистемы УправлениеДоступом позволяет работать с RLS в двух режимах: стандартном и производительном. Каждый из режимов имеет свои преимущества и недостатки относительно другого. Основные из них будут рассмотрены в тексте далее.

Для дальнейших скриншотов, примеров кода, а также для решения задачи будем использовать демонстрационную конфигурацию "Библиотека стандартных подсистем", редакция 3.1 (3.1.5.132).

Ограничения RLS описываются в роли для конкретного объекта. Например, ограничение на чтение документа _ДемоСчетНаОплатуПокупателю в роли
_ДемоЧтениеДокументовПокупателей описывается следующим образом:

 

 

 

 

Как мы видим, для описания ограничений используются специальные шаблоны. В данном случае #ДляОбъекта и #ПоЗначениям. Шаблоны, которые могут быть использованы в роли необходимо описать на вкладке “Шаблоны ограничений”:

 

 

В свою очередь, эти шаблоны можно скопировать из поставляемой роли ИзменениеУчастниковГруппДоступа.

Рассмотрим текст ограничения доступа подробнее.

#Если &ОграничениеДоступаНаУровнеЗаписейУниверсально #Тогда
#ДляОбъекта("")
#Иначе
#ПоЗначениям( "Документ._ДемоСчетНаОплатуПокупателю", "","",
"_ДемоОрганизации", "Организация",
"_ДемоГруппыПартнеров","Партнер", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","")
#КонецЕсли

 

Как мы видим, выбор шаблона зависит от параметра &ОграничениеДоступаНаУровнеЗаписейУниверсально, который как раз и определяет режим, в котором должно использоваться RLS — стандартный или производительный. Значение этого параметра хранится в параметрах сеанса, а в самой базе выбрать режим можно двумя способами:
 

  • Зайти в раздел Администрирование — Настройки пользователей и прав — Группы доступа — Вариант работы — Производительный

 


 

  • В окне “Все функции” изменить значение константы “Ограничивать доступ на уровне записей универсально” на ИСТИНА, если нужен производительный режим и, соответственно на ЛОЖЬ, если стандартный.

 

 

Соответственно, если &ОграничениеДоступаНаУровнеЗаписейУниверсально = ЛОЖЬ, то будет использоваться стандартный метод и выполняться код

#ПоЗначениям( "Документ._ДемоСчетНаОплатуПокупателю", "","",
"_ДемоОрганизации", "Организация",
"_ДемоГруппыПартнеров","Партнер", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "","", "",""), 

 

а если &ОграничениеДоступаНаУровнеЗаписейУниверсально = ИСТИНА, то будет использоваться производительный метод и выполняться код

#ДляОбъекта("").

Примечание. Подробнее о синтаксисе и использовании шаблонов можно почитать в их описании.

При стандартном режиме ограничение прописывается прямо в роли (установлен отбор по разрешенным организации и партнеру). Эти отборы добавляются к итоговому запросу при обращении к СУБД. При наличии нескольких ролей с описанными ограничениями все условия собираются в один запрос, растет количество левых соединений, повышается риск неправильного использования индексов, выбора неоптимального плана выполнения запроса, что значительно его усложняет и замедляет выполнение. А так как при стандартном режиме работы ограничения рассчитываются “на лету” при каждом обращении к данным (формирование списков справочников и документов, их открытие и записи), то работа пользователя может значительно замедлиться из-за сложности сформированного запроса.

Эту проблему решает включение производительного режима. При нём все отборы и ограничения не добавляются в запрос, раздувая его, а предварительно рассчитываются в некоторые ключи доступа и в итоговый запрос попадают только они, что увеличивает производительность. О ключах и их расчете подробнее далее.

Как мы видим, в ограничении роли для производительного режима не описаны никакие условия, нет никакой информации о видах доступа, по которым необходимо ограничивать данные. Где же они указаны? Для этого в подсистеме УправлениеДоступом предусмотрена специальная экспортная процедура ПриЗаполненииОграниченияДоступа(), который описывается в модуле менеджера объекта, указанного в роли.

Так, для документа _ДемоСчетНаОплатуПокупателю эта процедура описана следующим образом:

Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
	Ограничение.Текст =
	"РазрешитьЧтениеИзменение
	|ГДЕ
	|	ЗначениеРазрешено(Организация)
	|	И ЗначениеРазрешено(Партнер)";
…
КонецПроцедуры

 

Здесь мы видим, что ограничение описывается с помощью некоторых типов ограничения (РазрешитьЧтениеИзменение) и функций ограничений (ЗначениеРазрешено()). Это нужно понимать так: пользователю будет разрешено читать и изменять документ _ДемоСчетНаОплатуПокупателю, когда ему будут разрешены значения организации и партнера, указанные в этом документе.

Примечание. Подробно о типах, функциях, синтаксисе ограничений описано на сайте ИТС в разделе — Инструкции по разработке на 1С

— Библиотека стандартных подсистем 3.1.6. Документация

            — Глава 3. Настройка и использование подсистем при разработке конфигурации

                    — Управление доступом

                            — Разработка ограничений прав доступа

1С:ИТС Разработка ограничений прав доступа

Далее в статье рассмотрим кратко лишь некоторые.
 

Некоторые типы ограничений

Типы ограничения могут быть:

  • РазрешитьЧтениеИзменение
  • РазрешитьИзменениеЕслиРазрешеноЧтение
  • РазрешитьИзменение

 

Основным способом описания ограничений необходимо считать функцию ЗначениеРазрешено(). Функция выполняет поиск проверяемого значения среди разрешенных значений в группах доступа, профили которых предоставляют соответствующие права на список.

  • ЗначениеРазрешено(<Реквизит> [<проверяемые типы>] [, <уточнение сравнения 1> [, <уточнение сравнения 2>] …]), где проверяемые типы могут быть (значения непроверяемых типов запрещены, если не уточнены отдельно):
    • ТОЛЬКО <Имя таблицы>;
    • ТОЛЬКО (<Имя таблицы 1>, <Имя таблицы 2>, … );
    • КРОМЕ <Имя таблицы>;
    • КРОМЕ (<Имя таблицы 1>, <Имя таблицы 2>, … );
  • Уточнение сравнения может быть:
    • ПустаяСсылка КАК Ложь/Истина;
    • Неопределено КАК Ложь/Истина;
    • Null КАК Ложь/Истина;
    • Отключено КАК Ложь/Истина (только для функции ЗначениеРазрешено);
    • <Таблица> КАК Ложь/Истина (например, Справочник.Проекты КАК Истина).

 

Также существуют следующие функции:

  • ЧтениеОбъектаРазрешено
  • ЧтениеСпискаРазрешено
  • ИзменениеОбъектаРазрешено
  • ИзменениеСпискаРазрешено

Синтаксис этих функций аналогичен функции ЗначениеРазрешено().

Эти функции необходимо использовать, когда необходимо установить доступность (чтение/изменение) объекта в зависимости от доступности его реквизита. Например, документ _ДемоСчетНаОплатуПокупателю должен быть доступен, когда доступен его реквизит Организация. В таком случае ограничение будет описано как:

Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
	Ограничение.Текст =
	"РазрешитьЧтениеИзменение
	|ГДЕ
	|	ЧтениеОбъектаРазрешено(Организация)";
КонецПроцедуры
  • ДляВсехСтрок(<Условие>)

Функция выполняет проверку в строках с помощью логического «И». Используется для одновременного выполнения условия во всех строках табличной части объекта.

  • ДляОднойИзСтрок(<Условие>)

Функция выполняет проверку в строках с помощью логического «ИЛИ». Используется для выполнения условия хотя бы в одной строке табличной части объекта.

 

Примеры возможных ограничений

  • Организация и контрагент в шапке документа:
 Ограничение.Текст =

"РазрешитьЧтениеИзменение

|ГДЕ

|  ЗначениеРазрешено(Организация)

|И ЗначениеРазрешено(Контрагент)";

 

  • Организация в шапке документа, контрагент в табличной части, достаточно одного разрешенного контрагента:
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ЗначениеРазрешено(Организация)
|И ЗначениеРазрешено(Поставщики.Контрагент)";

 

  • Организация в шапке документа, контрагент в табличной части, достаточно одного разрешенного контрагента (если табличная часть пустая, тогда доступ по контрагенту разрешен):
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ЗначениеРазрешено(Организация)
|И ЗначениеРазрешено(Поставщики.Контрагент, Null КАК Истина)";

 

  • Организация в шапке документа, контрагент в табличной части, и требуется, чтобы все контрагенты были разрешены (если табличная часть пустая, тогда доступ по контрагенту запрещен):
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ЗначениеРазрешено(Организация)
|И ДляВсехСтрок(ЗначениеРазрешено(Поставщики.Контрагент))";

 

  • Организация и контрагент в табличной части, при этом достаточно, чтобы любая из пар организации с контрагентом была разрешена:
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ЗначениеРазрешено(Поставщики.Организация)
|И ЗначениеРазрешено(Поставщики.Контрагент)";

 

  • Организация и контрагент в табличной части, при этом требуется, чтобы все пары организации с контрагентом были разрешены:
	Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ДляВсехСтрок(
|      ЗначениеРазрешено(Поставщики.Организация)
|    И ЗначениеРазрешено(Поставщики.Контрагент))";

 

  • Организация и контрагент в табличной части, при этом требуется, чтобы одна из организаций и один из контрагентов были разрешены:
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ДляОднойИзСтрок(ЗначениеРазрешено(Поставщики.Организация))
|И ДляОднойИзСтрок(ЗначениеРазрешено(Поставщики.Контрагент))";

 

  • Отправитель – измерение составного типа, при этом требуется проверять только ссылки Справочник.Склады:
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|  ЗначениеРазрешено(Отправитель ТОЛЬКО Справочник.Склады)";

 

Отличительная особенность производительного режима RLS

Вернёмся к основной отличительной особенности производительного режима RLS. Она заключается в том, что в этом режиме расчет прав происходит предварительно и записывается в специальные таблицы (справочник и регистры сведений). Это позволяет достичь высокой производительности запросов с RLS, так как добавляет простой и статический фрагмент к текстам запросов в ролях. За счет этого обеспечивается одинаково хорошая скорость работы при различной прикладной логике ограничений доступа, при различных условиях и их комбинациях. Но, так как предварительный расчет прав доступа занимает некоторое время, поэтому изменения в правах вступают в силу с некоторой задержкой.

Для хранения этих предварительно рассчитанных данных (ключей) используются следующие таблицы:

  • справочник КлючиДоступа
  • регистр сведений КлючиДоступаКОбъектам
  • регистр сведений КлючиДоступаПользователей

Справочник КлючиДоступа имеет структуру:

 

 

В реквизитах Значение1 — Значение5 хранятся комбинации конкретных значений доступа. В зависимости от ограничений каждого конкретного типа объектов конфигурации состав значений разный. Например, как упоминалось выше, для документа _ДемоСчетНаОплатуПокупателю определено ограничение по Организации и Партнеру. Соответственно, будут сформированы ключи с возможными комбинациями организации и партнера.

В реквизит Хэш реквизит рассчитывается специальный хеш функции. Он позволяет быстро понять, существует ли уже в системе ключ с такой комбинацией значений или нет.

 

Структура регистров следующая:

 

Причем Объект РС КлючиДоступаКОбъектам имеет тип ОпределяемыйТип.ВладелецЗначенийКлючейДоступа, которые содержит в себе ссылки на все объекты, которые могут быть ограничены с помощью RLS.

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

Таким образом при проверке ограничений доступа вне зависимости от количества настроенных для конкретного проверяемого объекта видов доступа запрос всегда будет дополняться одним соединением с регистром «Ключи доступа к объектам» по проверяемому объекту и с регистром «Ключи доступа пользователей» по текущему пользователю:

 

 

Обновление ключей объектов и ключей доступа к ним выполняются регламентным заданием. А также ого может быть запущено из обработки “Обновление доступа на уровне записей”:

 

 

Эта обработка позволяет запускать процесс обновления ключей вручную, а также настраивать и контролировать процесс выполнения.

  • Запуск обработки выполняется по кнопке

 

 

  • Можно настроить обновление ключей по определенным объектам. Эта настройка выполняется по кнопке Ещё — Ручное управление… На этой форме можно выбрать конкретные справочники, документы или регистры, по которым необходимо обновить ключи, отметить их флажками, после этого запланировать обновление и запустить обработку:

 

 

  • Также есть возможность выводить более подробную информацию о ходе выполнения обработки

 

 

Для удобного написания и контроля текстов ограничений в комплекте поставки есть специальная обработка УправлениеДоступом:

 

 

Она позволяется в пользовательском режиме, без редактирования конфигурации формировать и проверять тексты ограничения доступа для объектов. Для этого необходимо во вкладке “Разработка ограничений доступа” необходимо выбрать список, ограничение на который нужно отредактировать:

 

 

После этого на форму загрузится текст ограничений из процедуры ПриЗаполненииОграниченияДоступа, а также шаблон ограничения в роли, а также кнопки для проверки текста вставки его в код:

 

 

При наличии ошибки в тексте ограничения и нажатии на кнопку “Проверить” появляется вкладка “(ошибки)”, в которой описаны ошибка как самого текста, так и всего внедрения механизма ограничений по записям для объекта:

 

 

 

Несколько конкретных примеров внедрения

Допустим, нам необходимо создать новый документ и подключить его к механизму ограничений RLS. Для этого необходимо выполнить следующие операции:

— создать новый документ ТестовыйДокументСОграничениями

 

 

— добавить объект в определяемые типы ВладелецЗначенийКлючейДоступа и ВладелецЗначенийКлючейДоступаДокумент.

Примечание. В определяемый тип ВладелецЗначенийКлючейДоступаДокумент добавляются документы. Справочники нужно добавить в ВладелецЗначенийКлючейДоступаОбъект, регистры сведений — в ВладелецЗначенийКлючейДоступаНаборЗаписей, регистры расчета — в ВладелецЗначенийКлючейДоступаНаборЗаписейРегистраРасчета.

 

— в процедуру ПриЗаполненииСписковСОграничениемДоступа общего модуля УправлениеДоступомПереопределяемый вставить текст

Списки.Вставить(Метаданные.Документы.ТестовыйДокументСОграничениями, Истина);

 

Процедура ПриЗаполненииСписковСОграничениемДоступа(Списки) Экспорт
	
…

Списки.Вставить(Метаданные.Документы.ТестовыйДокументСОграничениями, Истина);
	
КонецПроцедуры

 

— на форме документа в обработчики ПриЧтенииНаСервере и ПослеЗаписиНаСервере добавить следующий код:

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
	
	// СтандартныеПодсистемы.УправлениеДоступом
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
		МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом");
		МодульУправлениеДоступом.ПриЧтенииНаСервере(ЭтотОбъект, ТекущийОбъект);
	КонецЕсли;
	// Конец СтандартныеПодсистемы.УправлениеДоступом
	
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	
	// СтандартныеПодсистемы.УправлениеДоступом
	УправлениеДоступом.ПослеЗаписиНаСервере(ЭтотОбъект, ТекущийОбъект, ПараметрыЗаписи);
	// Конец СтандартныеПодсистемы.УправлениеДоступом
	
КонецПроцедуры

 

— создать новые роли для чтения и добавления/изменения нового документа: ЧтениеТестовыхДокументовСОграничениями и ДобавлениеИзменениеТестовыхДокументовСОграничениями. Для них определить соответствующие права (чтение, добавление, изменение), скопировать шаблон ограничений ДляОбъекта() из роли ИзменениеУчастниковГруппДоступа и прописать код ограничения доступа для необходимых прав:

#Если &ОграничениеДоступаНаУровнеЗаписейУниверсально #Тогда
#ДляОбъекта("")
#Иначе
ИСТИНА
#КонецЕсли

 

Примечание. В данном конкретном случае принимаем, что производительный режим RLS используется, поэтому ограничение для обычного режима не прописываем и в соответствующей ветке прописываем просто ИСТИНА.

 

 

 

  • Нужно для этого документа реализовать ограничение, чтобы были доступны только те документы, в которых доступны организация и подразделение. Необходимо выполнить следующие действия:

 

— в модуле менеджера документа в процедуре ПриЗаполненииОграниченияДоступа прописать текст ограничения:

Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
	
	Ограничение.Текст =
	"РазрешитьЧтениеИзменение
	|ГДЕ
	|	ЗначениеРазрешено(Организация)
	|	И ЗначениеРазрешено(Подразделение)";

КонецПроцедуры

 

— в пользовательском режиме создать профили доступа с созданными ранее ролями, группы доступа и прописать в них ограничения по организациям и подразделениям и назначить их пользователям:

 

 

 

— создать документы и запустить задание обновления ключей доступа.

В результате получим ограниченный список документов для тестового менеджера:

 

под полными правами

 

 

под ограниченными правами

 

  • Нужно реализовать ограничение, чтобы были доступны только те документы, в которых доступны организация и было доступно хотя бы одно место хранения из ТЧ Запасы.

— в модуле менеджера документа в процедуре ПриЗаполненииОграниченияДоступа прописать текст ограничения:

Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
	
	Ограничение.Текст =
	"РазрешитьЧтениеИзменение
	|ГДЕ
	|	ЗначениеРазрешено(Организация)
	|	И ДляОднойИзСтрок(ЗначениеРазрешено(Запасы.МестоХранения))";

КонецПроцедуры

 

— добавить вид ограничения в профиль доступа, прописать в группе доступа ограничения по местам хранения, обновить ключи:

 

 

 

В результате под пользователем с ограниченными правами увидим только те документы, у которых доступна организация и в ТЧ Запасы хотя бы в одной строке указан Розничный склад:

 

 

 

 

 

  • Рассмотрим пример, когда необходимо реализовать ограничение по какому-то новому реквизиту, тип которого не описан в доступных видах доступа. Реализуем такую задачу. Для этого нужно выполнить следующее:

— создать новый справочник ТестовыйРегион. Выполнить для него все те же операции, что и для самого документа ТестовыйДокументСОграничениями (роли можно создать новые или прописать в какие-то существующие, например для чтения/изменения документа. В данном примере это не принципиально. В ПриЗаполненииОграниченияДоступа прописать ограничение на само себя: ЗначениеРазрешено(Ссылка)).

— добавить ссылку и объект ТестовыйРегион в определяемые типы соотстветственно ЗначениеДоступа и ЗначениеДоступаОбъект

— в процедуру ПриЗаполненииВидовДоступа общего модуля УправлениеДоступомПереопределяемый вставить текст:

Процедура ПриЗаполненииСписковСОграничениемДоступа(Списки) Экспорт
	
…

ВидДоступа = ВидыДоступа.Добавить();
ВидДоступа.Имя = "ТестовыйРегион";
ВидДоступа.Представление = НСтр("ru = 'Тестовый регион'");
ВидДоступа.ТипЗначений   = Тип("СправочникСсылка.ТестовыйРегион");
	
КонецПроцедуры

 

— запустить обработку ОбновлениеВспомогательныхДанных (из Инструментов разработчика) и  обновить всё.

— добавить новый вид доступа в профиль доступа и определить конкретные ограничения в группе доступа:

 

 

 

— добавить реквизит в документ, вывести на форму, заполнить (скриншот от пользователя с полными правами):

 

 

— изменить текст ограничения в процедуре ПриЗаполненииОграниченияДоступа документа ТестовыйДокументСОграничениями, чтобы он учитывал новый реквизит:

Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
	
	Ограничение.Текст =
	"РазрешитьЧтениеИзменение
	|ГДЕ
	|	ЗначениеРазрешено(Организация)
	|	И ЗначениеРазрешено(ТестовыйРегион)";

КонецПроцедуры

 

— обновить ключи доступа.

В результате на пользователя с ограниченными правами распространяются ограничения по организациям (ООО Тестовая организация и Новые технологии ООО) и регионам (Центральный и Южный) и он получит такой список документов:

 

has been added to your cart:
Оформление заказа