Skip to content

Instantly share code, notes, and snippets.

@AskinNet
Last active May 26, 2025 04:25
Show Gist options
  • Save AskinNet/8bd65f5bd15425c998a3db848d030c90 to your computer and use it in GitHub Desktop.
Save AskinNet/8bd65f5bd15425c998a3db848d030c90 to your computer and use it in GitHub Desktop.
1C: Токен JWT. Практика.

Авторизация по токенам можно приделать к входу в базу,веб сервисам и http-сервисам. То есть внутри элементов <point>, <ws> и <httpServices>  файле default.vrd - публикации базы 1с, на вебсервере.

Выбор принципа авторизации.

По умолчанию во всех руководствах авторизация привязывается к имени пользователя. И надо заметить, что к имени объекта ПользователиИнформационнойБазы, а не к БСП-шному справочнику Пользователи. Это определяется значением ключа authenticationUserPropertyName.

Но его можно изменить на:

name ‑ для поиска используется свойство Имя.
OSUser ‑ для поиска используется свойство ПользовательОС.
email ‑ для поиска используется свойство АдресЭлектроннойПочты

Если эти поля не хотелось бы использовать по каким-то причинам, или же выдается ключ сторонней организацией, и его нужно привязать к пользователю, то можно использовать структуру (соответствие) КлючиСопоставленияПользователя объекта ПользователиИнформационнойБазы

К примеру:

ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени("ИвановИИ");  
ПользовательИБ.КлючиСопоставленияПользователя.Вставить("yandex", "[email protected]");  
ПользовательИБ.КлючиСопоставленияПользователя.Вставить("google","[email protected]");  
ПользовательИБ.КлючиСопоставленияПользователя.Вставить("jwt", "09876564321");

Ключом является aud из payload, а значением идентификатор, с которым нужно сопоставлять, значение sub. То есть, другим словами, ключом будет Получатель из примера кода ниже, а значением будет ТокенДоступа.КлючСопоставленияПользователя. При этом значение ключа authenticationUserPropertyName в публикации вместо "name", измениться на authenticationUserPropertyName="matchingKey".

Важно, так же что<accessTokenRecepientName> Получатель </accessTokenRecepientName> не обрамлено кавычками в vrd файле.

Пример.

Пример, создания ключа, авторизация по имени пользователя объекта ПользователиИнформационнойБазы:

// Переменные, комментарии
ИсходныйПароль = "пароль"; // "закрытый" ключ. сменить :-)

// с помощью этого ключа, зная алгоритм можно наделать много таких же токенов пропуска в 1с.
// потенциальная дыра. но можно применять и другой алгоритм.. но это уже в другой серии
СтрокаДД = ПолучитьДвоичныеДанныеИзСтроки(ИсходныйПароль);
КлючВВидеBase64 = Base64Строка(СтрокаДД);
Сообщить("Ключ: " + КлючВВидеBase64);

Эмитент = "BaseERP";    //обозначение того кто выдал.
Получатель = "BaseDoc"; // кому предназначен токен
//Вообще получатели это массив, то есть токен может сразу формироваться для нескольких получателей
//По этому полю-ключу возможно сопоставление пользователей

ВремяСоздания = ТекущаяУниверсальнаяДата() - Дата(1970,1,1,0,0,0);
// почему не ТекущаяДатаСеанса() ? 
// потому что время по unix, то есть в числом
// и время должно быть без часового пояса, иначе библиотека, которая 1с себе
// встроила прибавит еще часовой пояс, по нашему +5 от Гринвича, не от Москвы!
 
ВремяЖизни =  86400;   // в секундах, для тестов сделал сутки 

КлючСопоставленияПользователя  = "askin"; // имя пользователя, по умолчанию authenticationUserPropertyName=""name"" 

// формирование токена
ТокенДоступа = Новый ТокенДоступа;
ТокенДоступа.Эмитент = Эмитент; 
ТокенДоступа.Получатели.Добавить(Получатель); // их может быть несколько, поиск по ним
ТокенДоступа.ВремяСоздания = ВремяСоздания; 
ТокенДоступа.ВремяЖизни = ВремяЖизни;
ТокенДоступа.КлючСопоставленияПользователя = "askin";
ТокенДоступа.Подписать(АлгоритмПодписиТокенаДоступа.HS256, КлючВВидеBase64);  
// алгоритмов куча сделали. этот самый простой.

ТекстТокена = Строка(ТокенДоступа); 

Сообщить(ТекстТокена);
Сообщить("Bearer " + ТекстТокена); // для вставки, пример
Сообщить("http://localhost:88/token/hs/test1/ping?AccessToken=" + ТекстТокена); // пример
Сообщить("http://localhost:88/token?AccessToken=" + ТекстТокена); // пример

// текст нужно вставить куда нибудь внутрь `<point> или <ws> или <httpServices>`
ТекстВставкиВФайл_vrd = 
"	<accessTokenAuthentication>
|		<issuers>
|			<issuer name=""" + Эмитент + """
|			        authenticationClaimName=""sub""
|			        authenticationUserPropertyName=""name""
|			        keyInformation=""" + КлючВВидеBase64 + """/>
|		</issuers>
|       <accessTokenRecepientName>" + Получатель + "</accessTokenRecepientName>
|   </accessTokenAuthentication>";
Сообщить(ТекстВставкиВФайл_vrd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment