v8: Авторизация пользователей при входе в программу Ключевые слова: Авторизация пользователь вход запуск идентификация запрет
По хорошему при серьезном подходе к автоматизации нужно запрещать неавторизованный вход в программу.
Исключение могут составлять крайне редкие случаи, например, демо-версия конфигурации или конфигурация публичного пользования.
Но как правило, наряду с заведением пользователей в конфигураторе имеет смысл сделать в конфигурации справочник "Пользователи", в котором хранить пользователей, соответствующих пользователям в конфигураторе.
Это дает возможность некоторых вещей, например привязки к пользователю некоторых прав, которыми нельзя управлять с помощью метаданного "Роль", построение системы ограничения прав RLS, привязанной к текущему пользователю, сохранение в справочниках и документах информации об авторах объектов, индивидуальные особенности интерфейса, настроек отчетов, событий и т. д.
В этом выпуске будет рассмотрено, как в конфигурации организовать авторизацию пользователей при входе в программу.
Предполагается, что структура пользователей может быть иерархической и пользователи подчинены распределенным базам.
Кому иерархия и/или распределенные базы не нужны, тот может легко все поправить под свой вариант.
Итак. Для выполнения этой задачи в конфигурации требуется сделать нижеперечисленные настройки.
Добавляем в конфигурацию план обмена "РаспределенныеБазы".
Добавляем в конфигурацию иерархический справочник "Пользователи", подчиненный плану обмена "РаспределенныеБазы".
Добавляем в конфигурацию параметр сеанса "ТекущийПользователь" типа "СправочникСсылка.Пользователи".
Добавляем в конфигурацию параметр сеанса "ТекстСообщенияОбОшибкеПриЗапускеПрограммы" типа "Строка неограниченной длины".
Добавляем в конфигурацию параметр сеанса "ТекущийУзелРаспределеннойБазы" типа "ПланОбменаСсылка.РаспределенныеБазы".
Добавляем в конфигурацию константу "ЗапретитьЗапускПрограммыНовымПользователям" типа "Булево".
В модуль приложения в процедуру ПередНачаломРаботыСистемы() вставляем код
Если ПараметрыСеанса.ТекущийПользователь.Пустая() Тогда
Предупреждение(ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы, 60);
Отказ = Истина;
КонецЕсли;
В модуль внешнего соединения в процедуру ПриНачалеРаботыСистемы() вставляем код
Если ПараметрыСеанса.ТекущийПользователь.Пустая() Тогда
ВызватьИсключение(ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы);
Отказ = Истина;
КонецЕсли;
В модуль сеанса, в котором фирма "1С" рекомендует устанавливать параметры сеанса, в процедуру УстановкаПараметровСеанса() вставляем код
ПараметрыСеанса.ТекущийУзелРаспределеннойБазы = ПланыОбмена.РаспределенныеБазы.ЭтотУзел();
глУстановитьПараметрСеансаТекущийПользователь();
Туда же (в модуль сеанса) вставляем процедуру глУстановитьПараметрСеансаТекущийПользователь() и функцию глЕстьДействующиеПользователи()
Процедура глУстановитьПараметрСеансаТекущийПользователь()
Если ПустаяСтрока(ИмяПользователя()) Тогда
ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы =
"Вход в программу без авторизации невозможен.
|Заполните список пользователей в конфигураторе.";
ИначеЕсли СтрДлина(СокрЛП(ИмяПользователя())) > Метаданные.Справочники.Пользователи.ДлинаНаименования Тогда
Если Метаданные.Справочники.Пользователи.ДлинаНаименования = 1 Тогда
ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы =
"Имя пользователя не может быть длиннее 1 символа.
|Сократите имя пользователя в конфигураторе.";
Иначе
ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы =
"Имя пользователя не может быть длиннее " + Метаданные.Справочники.Пользователи.ДлинаНаименования + " символов.
|Сократите имя пользователя в конфигураторе.";
КонецЕсли;
Иначе
ТекстЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Пользователи.Ссылка КАК Пользователь
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| (НЕ Пользователи.ПометкаУдаления)
| И Пользователи.Владелец = &Владелец
| И (НЕ Пользователи.ЭтоГруппа)
| И Пользователи.Наименование = &Наименование";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Владелец", ПараметрыСеанса.ТекущийУзелРаспределеннойБазы);
Запрос.УстановитьПараметр("Наименование", ИмяПользователя());
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Если Константы.ЗапретитьЗапускПрограммыНовымПользователям.Получить()
И глЕстьДействующиеПользователи() Тогда
ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы =
"Автоматическое создание новых записей в справочнике ""Пользователи"" запрещено.
|Обратитесь к администратору для добавления новой записи.";
Иначе
Попытка
Спр = Справочники.Пользователи.СоздатьЭлемент();
Спр.УстановитьНовыйКод();
Спр.Владелец = ПараметрыСеанса.ТекущийУзелРаспределеннойБазы;
Спр.Наименование = ИмяПользователя();
Спр.ПолноеНаименование = ПолноеИмяПользователя();
Спр.Записать();
ПараметрыСеанса.ТекущийПользователь = Спр.Ссылка;
Исключение
ПараметрыСеанса.ТекстСообщенияОбОшибкеПриЗапускеПрограммы = ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Иначе
Выборка = Результат.Выбрать();
Выборка.Следующий();
ПараметрыСеанса.ТекущийПользователь = Выборка.Пользователь;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция глЕстьДействующиеПользователи()
ТекстЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Пользователи.Ссылка КАК Пользователь
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| (НЕ Пользователи.ПометкаУдаления)
| И Пользователи.Владелец = &Владелец
| И (НЕ Пользователи.ЭтоГруппа)";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Владелец", ПараметрыСеанса.ТекущийУзелРаспределеннойБазы);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
Собственно все. Теперь программа не запустится, если список пользователей в конфигураторе пустой.
И напоследок немного по логике работы.
Параметр сеанса "ТекущийПользователь" вместо комбинации двух одноименных экспортных переменных "глТекущийПользователь" в модуле приложения и модуле внешнего соединения выбран потому, что к нему можно привяхать RLS, а к глобальной переменной нет.
Параметр сеанса "ТекстСообщенияОбОшибкеПриЗапускеПрограммы" заведен исключительно для того, чтобы определить, что пользователь неавторизован и что-то нужно сказать этот самый текст перед принужительным завершением работы программы.
Если устанавливать параметры сеанса в модуле приложения в процедуре ПередНачаломРаботыСистемы() и в модуле внешнего соединения в процедуре ПриНачалеРаботыСистемы(), то этот объект метаданных совершенно не нужен, но, раз уж фирма "1С" рекомендует устанавливать параметры сеанса в модуле сеанса...
Константа "ЗапретитьЗапускПрограммыНовымПользователям" создана для того, чтобы при необходимости запретить автоматически программно создавать новых пользователей в справочнике "Пользователи". Может пригодиться в принципе кому-нибудь.
В модуле внешнего соединения проверка авторизованности пользователя выполняется в процедуре ПриНачалеРаботыСистемы(), а не в процедуре ПередНачаломРаботыСистемы() потому, что в модуле внешнего соединения нет события ПередНачаломРаботыСистемы().
Именно поэтому отказаться от запуска программы уже нельзя, но... нужно, поэтому вызываем исключение с заданным текстом ошибки.
В процедуре глУстановитьПараметрСеансаТекущийПользователь() производится попытка авторизовать пользователя, в случае неудачи параметр сеанса "ТекущийПользователь" остается неустановленным, зато устанавливается параметр сеанса "ТекстСообщенияОбОшибкеПриЗапускеПрограммы".
Пользователь останется неавторизованным в том случае, если:
- Имя пользователя пустое, то есть список пользователей в конфигураторе пустой;
- Имя пользователя длиннее размерности наименования справочника "Пользователи";
- Пользователя нет в справочнике "Пользователи", при этом запрещено запускать программу новым пользователям и в справочнике "Пользователи" есть хоть один пользователь.
Проверка на наличие хотя бы одного пользователя в справочнике "Пользователи" делается для того, чтобы не получилось ситуации, когда в программе установили константу "ЗапретитьЗапускПрограммыНовымПользователям", удалили всех пользователей в справочнике "Пользователи", закрыли программу и... больше никогда не смогли в нее зайти;
- Пользователя нет в справочнике "Пользователи", при этом разрешено запускать программу новым пользователям или в справочнике "Пользователи" нет ни одного пользователя, но при попытке создать пользователя произошла какая-то ошибка и пользователь не создался.
Да, и еще напоследок. Не забывайте, что модуль сеанса выполняется в привелигированном режиме, а поэтому можно смело закрывать права на справочник "Пользователи" тем пользоватям, кто недостоин столь высоких прав. Я сказал можно? Нужно! |