Автоматическая смена паролей пользователей в 1С

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

Для реализации задачи по "смене паролей" нам понадобятся следующие изменения в конфигурации:

  • Две новых константы.
  • Два новых реквизита в справочник "пользователи".
  • Новая общая форма для ввода пароля, чтобы было красиво со *****.
  • Общий модуль с несколькими процедурами (можно процедуры поместить в любой существующий модуль).
  • Изменить модуль приложения (кусок при начале работы системы).

Итак начнем.

  1. Создаем новые константы:
  2. Не забываем задать права на "чтение" для обычных пользователей
  3. Добавляем возможность настраивать эти константы, в общую форму "настройки параметров учета" (ну или в другую форму, зависит от конфигурации)
  4. Добавляем непосредственно на форму:
  5. Переходим к пользователям, добавляем два реквизита в справочник (ДатаСменыПароля - булево, ТекущийПароль - строка 50):
  6. Дату смены пароля можно вывести на форму и сделать недоступной.
  7. Теперь добавляем новую общую форму "ФормаПароля", с одним единственным строковым реквизитом, сюда будут вводить пароль:
  8. На форме один реквизит "Пароль", с флажком "режим пароля":
  9. Код при закрытии формы, в одну строку:
    Процедура ОсновныеДействияФормыОК(Кнопка)
    	ЭтаФорма.Закрыть(СокрЛП(Пароль));
    КонецПроцедуры
    ​
  10. С интерфейсом покончено, теперь меняем общие модули.
  11. Сначала открываем модуль обычного приложения и вставляем в него новую функцию ее вызов:
    Процедура ПриНачалеРаботыСистемы()
    .....................
    Если Не СменаПароляПользователя() Тогда
    	Возврат;
    КонецЕсли;
    ......................
    ......................
    ......................
    ......................
    КонецПроцедуры	​
  12. Ниже или выше вставляем основную функцию "велосипеда":
    //Код основной функции смены пароля:
    Функция СменаПароляПользователя()
    	Если Константы.ИспользоватьСменуПаролей.Получить() = Ложь Тогда
    		Возврат Истина;
    	КонецЕсли;
    	
    	ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();		
    	
    	Если ПользовательИБ.ЗапрещеноИзменятьПароль Тогда
    		//флаг автоматически освобождает пользователи от смены пароля
    		Возврат Истина;		
    	КонецЕсли;
    	
    	мТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;
    	Если ЗначениеЗаполнено(мТекущийПользователь) И (ТекущаяДата() - мТекущийПользователь.ДатаСменыПароля) / 86400 > Константы.ПериодДействияПароля.Получить() Тогда
    		МенятьПароль = Истина;			
    	Иначе
    		МенятьПароль = Ложь;
    	КонецЕсли;
    	
    	Если МенятьПароль И РольДоступна("ПолныеПрава") Тогда
    		//для полных прав оставим возможность пропустить событие
    		Если Вопрос(НСтр("ru = 'Время менять пароль, сменить?'"), РежимДиалогаВопрос.ДаНет, 60) <> КодВозвратаДиалога.Да Тогда
    			МенятьПароль = Ложь;	
    		КонецЕсли;
    	КонецЕсли;
    	
    	Если Не МенятьПароль Тогда
    		Возврат Истина; //не надо менять пароль		
    	КонецЕсли;
    	
    	Предупреждение("Время действия пароля для 1С истекло, необходимо изменить пароль!", 2); 
    	
    	СменаПрошлаУспешно = Ложь;
    	
    	Пока Не СменаПрошлаУспешно Цикл
    		
    		ПарольВведен = Ложь;
    		Пока Не ПарольВведен Цикл
    			Форма = ПолучитьОбщуюФорму("ФормаПароля");
    			Форма.Заголовок = "Новый пароль на вход в базу";
    			Пароль = Форма.ОткрытьМодально();
    			Если Не ЗначениеЗаполнено(Пароль) Или СтрДлина(Пароль) < 4 Тогда //небольшя проверка на сложность пароля
    				Предупреждение("Пароль не может быть пустой и меньше 4х символов в длину!");
    				Продолжить;	
    			КонецЕсли;
    			
    			Форма.Заголовок = "Повторите пароль";
    			Форма.Пароль = "";
    			Пароль2 = Форма.ОткрытьМодально();
    			Если Пароль <> Пароль2 Тогда
    				Предупреждение("Пароли не совпадают!");
    				Продолжить;	
    			КонецЕсли;
    			Прервать;
    		КонецЦикла;
    		
    		Если Хеш.МД5(Пароль) = мТекущийПользователь.ТекущийПароль Тогда
    			Предупреждение("Пароль совпадает с вашим текущим паролем!");
    			Продолжить;
    		КонецЕсли;
    		
    		ПользовательИБ.Пароль = Пароль;
    		Попытка 
    			ПользовательИБ.Записать();
    		Исключение
    			Если Вопрос("Не удалось записать новый пароль, попробуйте усложнить пароль,
    				|повторить ввод?", РежимДиалогаВопрос.ДаНет, 60) <> КодВозвратаДиалога.Да Тогда
    				Прервать;
    			КонецЕсли;			
    		КонецПопытки;
    		
    		СменаПрошлаУспешно = Истина;
    	КонецЦикла;
    	
    	Если Не СменаПрошлаУспешно Тогда
    		ЗавершитьРаботуСистемы(Ложь);	
    		Возврат Ложь;
    	КонецЕсли;
    	
    	мТекущийПользовательОбъект = мТекущийПользователь.ПолучитьОбъект();
    	мТекущийПользовательОбъект.ДатаСменыПароля 	= ТекущаяДата();
    	мТекущийПользовательОбъект.ТекущийПароль 	= Хеш.МД5(Пароль);
    	мТекущийПользовательОбъект.Записать();	
    	
    	Возврат Истина;
    КонецФункции
  13. Обратите внимание на наличие такой строки Хеш.МД5(Пароль) - это вспомогательная функция, предназначена здесь исключительно чтобы скрыть пароль от посторонних глаз "особо продвинутых", хоть реквизит "ТекущийПароль" нигде не выведен, т.е. полностью недоступен для рядовых пользователей, все же не хочется пароль держать в не зашифрованном виде...
  14. Для работы функции МД5(Пароль) надо создать общий модуль с именем Хеш и поместить в него функции описанные ниже. Можно и в любой другой модуль..
    //Код модуля ХЕШ:
    
    Функция ХэшБлоками(Строка, ДлинаБлока = 10, hash = 0, M = 31, TABLE_SIZE = 18446744073709551616)
    	
    	НачПозиция = 1; ДлинаСтроки = СтрДлина(Строка); Пока НачПозиция <= ДлинаСтроки Цикл СтрокаБлока = Сред(Строка, НачПозиция, ДлинаБлока); Для к = 1 По СтрДлина(СтрокаБлока) Цикл hash = M * hash + КодСимвола(СтрокаБлока, к) КонецЦикла; hash = hash % TABLE_SIZE; НачПозиция = НачПозиция + ДлинаБлока КонецЦикла; Возврат hash
    	
    КонецФункции
    
    Функция ХэшБлокамиСОбраткой(Строка, ДлинаБлока = 10, hash = 0, M = 31, TABLE_SIZE = 18446744073709551616)
    	
    	НачПозиция = 1; ДлинаСтроки = СтрДлина(Строка); Пока НачПозиция <= ДлинаСтроки Цикл СтрокаБлока = Сред(Строка, НачПозиция, ДлинаБлока); Для к = 1 По СтрДлина(СтрокаБлока) Цикл hash = M * hash + КодСимвола(СтрокаБлока, к) КонецЦикла; hash = hash % TABLE_SIZE; НачПозиция = НачПозиция + ДлинаБлока КонецЦикла; Пока НачПозиция > 0 Цикл СтрокаБлока = Сред(Строка, НачПозиция, ДлинаБлока); Для к = -СтрДлина(СтрокаБлока) По -1 Цикл hash = M * hash + КодСимвола(СтрокаБлока, -к) КонецЦикла; hash = hash % TABLE_SIZE; НачПозиция = НачПозиция - ДлинаБлока КонецЦикла; Возврат hash
    	
    КонецФункции
    
    Функция Из_Число_В_16(Знач Значение)
    	
    	Результат = ""; Пока Значение > 0 Цикл Остат = Значение % 16; Значение = (Значение - Остат) / 16; Результат = Сред("0123456789ABCDEF", Остат + 1, 1) + Результат КонецЦикла; Возврат Результат
    
    КонецФункции
    
    Функция МД5(КодируемаяСтрока) Экспорт 
    	
    	Попытка
    		ЗначениеВозврата = Из_Число_В_16(ХэшБлоками(КодируемаяСтрока,, 5381, 33));
    	Исключение
    		ЗначениеВозврата = Неопределено;
    	КонецПопытки;	
    	
         
        Возврат ЗначениеВозврата; 
         
    КонецФункции​
  15. В основной функции сделана поблажка для пользователей с "полными правами", им разрешено не менять пароль в обязательном порядке именно сейчас. Смотри строку "Если МенятьПароль И РольДоступна("ПолныеПрава") Тогда"
  16. Если некоторым пользователям не надо менять пароль, допустим какая-то общая учетка на складе..., то ставим через конфигуратор в пользователя флаг:
Добавить комментарий