ШаблонНастройкиВторогоФактораАутентификации.HTTPЗапросНаАутентификацию

Свойства · AuthenticationHTTPRequest

Тип: HTTPЗапрос. Содержит запрос на аутентфикацию второго фактора.

Полное описание, параметры и ограничения

ШаблонНастройкиВторогоФактораАутентификации.HTTPЗапросНаАутентификацию (SecondAuthenticationFactorSettingTemplate.AuthenticationHTTPRequest)

ШаблонНастройкиВторогоФактораАутентификации (SecondAuthenticationFactorSettingTemplate)

HTTPЗапросНаАутентификацию (AuthenticationHTTPRequest)

Доступен, начиная с версии 8.3.14.

Использование:
Чтение и запись.
Описание:
Тип: HTTPЗапрос.
Содержит запрос на аутентфикацию второго фактора.
Доступность:

Сервер, толстый клиент.

Примечание:
Свойство должно быть заполнено.
Использование в версии:

Доступен, начиная с версии 8.3.14.

Методическая информация

Практические примеры

Создать и разобрать два своих native шаблона второго фактора без записи

Полная штатная фабрика → два HTTP child → два собственных шаблона → локальный consumer двух строк. Каждый реальный native field сверяется с конечным собственным источником, а хранилище остаётся пустым. Это не вход, не вызов провайдера и не рекомендация безопасности.

Где и как запускать

Полный общий модуль МФА85Черновики: только неглобальный Server+ServerCall; собственная новая FileCF Windows/толстый управляемый клиент.

Подготовка

  1. Этот опыт — каталог объектов настройки, а не работающий второй фактор входа. Никакие HTTP-запросы, MFA, SMS, почта, реальные секреты, QR или токены здесь не выполняются. Все действия ниже выполняет человек только в будущей новой своей лаборатории; авторство/статические проверки не создавали ИБ и не меняли настройки.

  2. В отдельной новой Windows VM вручную создайте совершенно новую файловую ИБ, не копию рабочей: C:\1c-labs\OwnMFATemplates85_2fac7b4e-b263-4cc1-86e5-09d540f0f380\IB. В Конфигураторе: имя конфигурации УчебныеШаблоныМФА85, платформа 8.5.1.1343, режим совместимости НеИспользовать, ОсновнойРежимЗапуска УправляемоеПриложение. Никаких объектов данных, регистров, обработок, сервисов, заданий, подписок, разделителей или расширений.

  3. Создайте только одну роль ШаблоныМФА85. В её свойствах прав конфигурации явно предоставьте Администрирование, АдминистрированиеДанных, АктивныеПользователи, запуск собственного толстого клиента и открытие собственной общей формы. Native ПолучитьПользователей требует административных прав; ПолучитьСоединенияИнформационнойБазы требует АктивныеПользователи. Совпадение имени роли не доказывает её права, реальные отказы не обходятся.

  4. Через Администрирование → Пользователи в своей новой ИБ создайте ровно одного нового пользователя МФА85Ученик, назначьте только свою роль. Не используйте действующий рабочий пароль и не показывайте его в учебнике. НастройкиВторогоФактораАутентификации должны быть пустым native массивом; здесь эти настройки только читаются/Количество=0 и не создаются. Закройте Конфигуратор перед опытом, оставьте одно соединение своего пользователя.

  5. Создайте два неглобальных общих модуля МФА85Черновики и МФА85Хранилище: Сервер Да, ВызовСервера Да; КлиентОбычноеПриложение Нет, КлиентУправляемоеПриложение Нет, ВнешнееСоединение Нет, Привилегированный Нет; ПовторноеИспользованиеВозвращаемыхЗначений НеИспользовать. Первый MAIN вставьте целиком в первый модуль, второй MAIN целиком во второй. В обоих полные свои helpers; никакого импорта неизвестной обработки или БСП.

  6. Создайте одну общую управляемую форму ШаблоныМФА85. Реквизиты: ПаспортUUID85 Строка(36), Текст85 Строка неограниченной длины, Согласие85 Булево, Шаг85 Строка(7). Поля привяжите через ПутьКДанным к одноимённым реквизитам; ПаспортUUID85 и Текст85 только просмотр. Команды Просмотр85 и ОдинЭтап85 с одноимёнными действиями/кнопками. События ПриСозданииНаСервере2/ПриОткрытии1 назначьте настоящим обработчикам полного FORM. APP целиком разместите в модуле управляемого приложения, ПриНачалеРаботыСистемы0. Нативные события вручную не вызывайте.

  7. Обновите только эту новую конфигурацию базы, закройте Конфигуратор, запустите собственный толстый управляемый клиент. Серверный Паспорт85 проверяет точный File-путь, версию/NoUse, пустую модель, состав модулей/формы/роли, одного фактического пользователя с его UUID, пустые настройки второго фактора и одно соединение. UUID реквизита — реальный UUID пользователя из штатной фабрики, не UUID пути/шаблона. В следующих RPC он сверяется до и после действий.

  8. Нажмите Просмотр85 до каких-либо записей. Получите две строки A/B и 0 сохранённых шаблонов. СоздатьШаблон() — реальная native фабрика; Новый Шаблон... и Новый Менеджер... отсутствуют и не применяются. GetTemplates0/FindByName1 читают полное состояние; исходное хранилище обязано быть пустым. При чужом шаблоне/пользователе/несовпадении СТОП, ничего не удалять.

  9. Наш конечный fixture: имена MFA85_A_2fac7b4e-b263-4cc1-86e5-09d540f0f380 и MFA85_B_2fac7b4e-b263-4cc1-86e5-09d540f0f380. У каждого native HTTPЗапрос для start и result, POST/POST, ровно Content-Type=application/json и X-Own-Lab=<UUID>. Четыре ASCII URI относительные, без host: /own-mfa85/<UUID>/A/start, /A/result, /B/start, /B/result. Body — ровно собственный JSON lab/slot/action, UTF8 и НеИспользоватьBOM; это несекретные данные local preview, не поддерживаемый реальный провайдер.

  10. Для опыта записи выберите saveA, отдельно явно установите Согласие85 и нажмите ОдинЭтап85. Полный whitelist 0 проверяется перед Записать0, затем свежие GetTemplates/FindByName и все пять native полей с полными полями двух HTTP child проверяются в состоянии A/1. Согласие потребляется перед RPC. Потом выберите saveB и дайте новое согласие: состояние AB/2. Это будущая попытка записи только своих новых шаблонов, не применение MFA к пользователю.

  11. Удаление — два отдельных намеренных этапа, не автоматическое исправление: deleteB с новым согласием проверяет полный AB/2 и удаляет только найденный собственный B, затем свежий A/1. deleteA с новым согласием проверяет A/1, затем пустое /0. Нельзя выбирать этап лишь по количеству: код проверяет все имена, типы, методы, URI, заголовки, тела и наличие/отсутствие обоих точных имён.

  12. Записать() и Удалить() — процедуры, без возвращаемого Булево. Ни False, ни вымышленная ссылка не подставляются как признак успеха. После любой ошибки RPC, native операции, readback или обработки результата пульт sticky СТОП и снимает согласие. Исход записи/удаления может быть неизвестен; повтор, rollback и автоматическое удаление не делаются. Не переоткрывайте форму ради снятия СТОП: сначала отдельно исследуйте фактическое состояние собственной лаборатории.

  13. ПолучитьТелоКакСтроку возвращает Строка/Неопределено; fresh persisted readback может отказать. Тогда СТОП без выдуманного тела, чтения неизвестного файла или продолжения удаления. Readback не гарантирует атомарность/отсутствие конкурентных изменений. Мы не обещаем, что хранение запроса доказывает его отправку, подстановку secret, совместимость с провайдером или успешный MFA вход.

  14. В HBK GetTemplates/FindByName написано право Администратор, Create/Write/Delete — Администрирование. Это формулировки справки, не предлагаемый новый enum права или имя роли. Одноаргументной ПравоДоступа нет; реальные штатные ошибки сохраняются. НастройкаВторогоФактораАутентификации, её неподтверждённая фабрика и enum обработчика НЕ входят в PRIMARY этих двух уроков.

Функция Паспорт85() Экспорт
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnMFATemplates85_2fac7b4e-b263-4cc1-86e5-09d540f0f380\IB"";" Тогда
        ВызватьИсключение "Только новая собственная файловая ИБ по точному пути";
    КонецЕсли;
    Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или ПривилегированныйРежим() Или ТранзакцияАктивна() Тогда
        ВызватьИсключение "Не совпали версия/своя конфигурация/NoUse/непривилегированный контекст";
    КонецЕсли;
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0
        Или Метаданные.Константы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0
        Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
        Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0
        Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0
        Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0
        Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0
        Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0
        Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Или Метаданные.HTTPСервисы.Количество() <> 0
        Или Метаданные.WebСервисы.Количество() <> 0 Или Метаданные.СервисыИнтеграции.Количество() <> 0
        Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0
        Или Метаданные.Отчеты.Количество() <> 0 Или Метаданные.Обработки.Количество() <> 0 Тогда
        ВызватьИсключение "Только пустая собственная прикладная модель без интеграций и заданий";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации()
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
        ВызватьИсключение "Расширения базы и сеанса запрещены";
    КонецЕсли;
    Если Метаданные.ОбщиеМодули.Количество() <> 2 Или Метаданные.ОбщиеФормы.Количество() <> 1
        Или Метаданные.ОбщиеФормы.Найти("ШаблоныМФА85") = Неопределено Или Метаданные.Роли.Количество() <> 1 Тогда
        ВызватьИсключение "Нужны только два своих модуля, один пульт и одна роль";
    КонецЕсли;
    Для Каждого ИмяМодуля Из СтрРазделить("МФА85Черновики,МФА85Хранилище", ",") Цикл
        Модуль = Метаданные.ОбщиеМодули.Найти(ИмяМодуля);
        Если Модуль = Неопределено Тогда
            ВызватьИсключение "Нет полного собственного серверного модуля";
        КонецЕсли;
        Если Модуль.Глобальный Или Не Модуль.Сервер Или Не Модуль.ВызовСервера
            Или Модуль.КлиентОбычноеПриложение Или Модуль.КлиентУправляемоеПриложение
            Или Модуль.ВнешнееСоединение Или Модуль.Привилегированный
            Или Модуль.ПовторноеИспользованиеВозвращаемыхЗначений <> Метаданные.СвойстваОбъектов.ПовторноеИспользованиеВозвращаемыхЗначений.НеИспользовать Тогда
            ВызватьИсключение "Оба модуля только Server+ServerCall, без привилегий и кеша";
        КонецЕсли;
    КонецЦикла;
    Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователь = Неопределено Или ТипЗнч(Пользователь) <> Тип("ПользовательИнформационнойБазы") Тогда
        ВызватьИсключение "Нет настоящего текущего пользователя";
    КонецЕсли;
    Если Пользователь.Имя <> "МФА85Ученик" Тогда
        ВызватьИсключение "Только собственный учебный пользователь";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1 Тогда
        ВызватьИсключение "Должен быть только один собственный пользователь";
    КонецЕсли;
    Свой = Пользователи[0];
    Если ТипЗнч(Свой) <> Тип("ПользовательИнформационнойБазы") Или Свой.Имя <> Пользователь.Имя
        Или Свой.УникальныйИдентификатор <> Пользователь.УникальныйИдентификатор Тогда
        ВызватьИсключение "Полный свежий список не совпал с пользователем собственного сеанса";
    КонецЕсли;
    Настройки = Свой.НастройкиВторогоФактораАутентификации;
    Если ТипЗнч(Настройки) <> Тип("Массив") Или Настройки.Количество() <> 0 Тогда
        ВызватьИсключение "Нельзя сохранять или удалять учебные шаблоны, связанные с настройками пользователя";
    КонецЕсли;
    СвояРоль = Метаданные.Роли.Найти("ШаблоныМФА85");
    Если СвояРоль = Неопределено Или Не Свой.Роли.Содержит(СвояРоль) Тогда
        ВызватьИсключение "Нет собственной явно подготовленной роли";
    КонецЕсли;
    ЧислоРолей = 0;
    Для Каждого Роль Из Свой.Роли Цикл
        Если Роль <> СвояРоль Тогда
            ВызватьИсключение "Чужая роль запрещена";
        КонецЕсли;
        ЧислоРолей = ЧислоРолей + 1;
    КонецЦикла;
    Если ЧислоРолей <> 1 Или ПолучитьСоединенияИнформационнойБазы().Количество() <> 1 Тогда
        ВызватьИсключение "Только своя единственная роль и одно соединение";
    КонецЕсли;
    Возврат Строка(Свой.УникальныйИдентификатор);
КонецФункции

Функция ИмяШаблона85(Слот)
    Если Слот <> "A" И Слот <> "B" Тогда
        ВызватьИсключение "Разрешены только собственные два слота A/B";
    КонецЕсли;
    Возврат "MFA85_" + Слот + "_2fac7b4e-b263-4cc1-86e5-09d540f0f380";
КонецФункции

Функция Адрес85(Слот, Действие)
    ИмяШаблона85(Слот);
    Если Действие <> "start" И Действие <> "result" Тогда
        ВызватьИсключение "Только собственные start/result";
    КонецЕсли;
    Возврат "/own-mfa85/2fac7b4e-b263-4cc1-86e5-09d540f0f380/" + Слот + "/" + Действие;
КонецФункции

Функция Тело85(Слот, Действие)
    Адрес85(Слот, Действие);
    Возврат "{""lab"":""2fac7b4e-b263-4cc1-86e5-09d540f0f380"",""slot"":""" + Слот + """,""action"":""" + Действие + """}";
КонецФункции

Функция СобственныйЗапрос85(Слот, Действие)
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Content-Type", "application/json");
    Заголовки.Вставить("X-Own-Lab", "2fac7b4e-b263-4cc1-86e5-09d540f0f380");
    Запрос = Новый HTTPЗапрос(Адрес85(Слот, Действие), Заголовки);
    Запрос.УстановитьТелоИзСтроки(Тело85(Слот, Действие), КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    ПроверитьЗапрос85(Запрос, Слот, Действие);
    Возврат Запрос;
КонецФункции

Процедура ПроверитьЗапрос85(Запрос, Слот, Действие)
    Если ТипЗнч(Запрос) <> Тип("HTTPЗапрос") Тогда
        ВызватьИсключение "Нужен настоящий собственный HTTPЗапрос, не структурная подмена";
    КонецЕсли;
    Если ТипЗнч(Запрос.АдресРесурса) <> Тип("Строка") Или Запрос.АдресРесурса <> Адрес85(Слот, Действие)
        Или ТипЗнч(Запрос.Заголовки) <> Тип("Соответствие") Или Запрос.Заголовки.Количество() <> 2 Тогда
        ВызватьИсключение "Не совпали полный собственный URI без host и число заголовков";
    КонецЕсли;
    Для Каждого Заголовок Из Запрос.Заголовки Цикл
        Если ТипЗнч(Заголовок.Ключ) <> Тип("Строка") Или ТипЗнч(Заголовок.Значение) <> Тип("Строка") Тогда
            ВызватьИсключение "Заголовки собственного запроса должны быть строковыми";
        КонецЕсли;
        Если Заголовок.Ключ = "Content-Type" Тогда
            Если Заголовок.Значение <> "application/json" Тогда
                ВызватьИсключение "Не совпал собственный Content-Type";
            КонецЕсли;
        ИначеЕсли Заголовок.Ключ = "X-Own-Lab" Тогда
            Если Заголовок.Значение <> "2fac7b4e-b263-4cc1-86e5-09d540f0f380" Тогда
                ВызватьИсключение "Чужой UUID заголовка";
            КонецЕсли;
        Иначе
            ВызватьИсключение "Чужой заголовок запрещён";
        КонецЕсли;
    КонецЦикла;
    Тело = Запрос.ПолучитьТелоКакСтроку();
    Если Тело = Неопределено Или ТипЗнч(Тело) <> Тип("Строка") Или Тело <> Тело85(Слот, Действие) Тогда
        ВызватьИсключение "Тело изменено или не возвращается как строка; СТОП без чтения неизвестного файла";
    КонецЕсли;
КонецПроцедуры

Функция СоздатьСвойШаблон85(Слот)
    Шаблон = ШаблоныНастроекВторогоФактораАутентификации.СоздатьШаблон();
    Если ТипЗнч(Шаблон) <> Тип("ШаблонНастройкиВторогоФактораАутентификации") Тогда
        ВызватьИсключение "Нужен объект настоящей штатной фабрики";
    КонецЕсли;
    Шаблон.Имя = ИмяШаблона85(Слот);
    Шаблон.HTTPЗапросНаАутентификацию = СобственныйЗапрос85(Слот, "start");
    Шаблон.МетодHTTPЗапросаНаАутентификацию = "POST";
    Шаблон.HTTPЗапросНаПроверкуРезультатаАутентификации = СобственныйЗапрос85(Слот, "result");
    Шаблон.МетодHTTPЗапросаНаПроверкуРезультатаАутентификации = "POST";
    ПроверитьШаблон85(Шаблон, Слот);
    Возврат Шаблон;
КонецФункции

Процедура ПроверитьШаблон85(Шаблон, Слот)
    Если ТипЗнч(Шаблон) <> Тип("ШаблонНастройкиВторогоФактораАутентификации") Тогда
        ВызватьИсключение "Нужен настоящий native шаблон";
    КонецЕсли;
    Если ТипЗнч(Шаблон.Имя) <> Тип("Строка") Или Шаблон.Имя <> ИмяШаблона85(Слот)
        Или ТипЗнч(Шаблон.МетодHTTPЗапросаНаАутентификацию) <> Тип("Строка") Или Шаблон.МетодHTTPЗапросаНаАутентификацию <> "POST"
        Или ТипЗнч(Шаблон.МетодHTTPЗапросаНаПроверкуРезультатаАутентификации) <> Тип("Строка") Или Шаблон.МетодHTTPЗапросаНаПроверкуРезультатаАутентификации <> "POST" Тогда
        ВызватьИсключение "Имя или методы собственных запросов изменены";
    КонецЕсли;
    ПроверитьЗапрос85(Шаблон.HTTPЗапросНаАутентификацию, Слот, "start");
    Если Шаблон.HTTPЗапросНаПроверкуРезультатаАутентификации = Неопределено Тогда
        ВызватьИсключение "У нашего собственного finite fixture обязателен запрос результата";
    КонецЕсли;
    ПроверитьЗапрос85(Шаблон.HTTPЗапросНаПроверкуРезультатаАутентификации, Слот, "result");
КонецПроцедуры

Процедура СверитьХранилище85(Ожидаемые)
    Фактические = ШаблоныНастроекВторогоФактораАутентификации.ПолучитьШаблоны();
    Если ТипЗнч(Фактические) <> Тип("Массив") Или Фактические.Количество() <> СтрДлина(Ожидаемые) Тогда
        ВызватьИсключение "Полный объём шаблонов не совпал с собственным состоянием";
    КонецЕсли;
    Встреченные = Новый Соответствие;
    Для Каждого Шаблон Из Фактические Цикл
        Если ТипЗнч(Шаблон) <> Тип("ШаблонНастройкиВторогоФактораАутентификации") Тогда
            ВызватьИсключение "Чужой тип элемента хранилища";
        КонецЕсли;
        Слот = "";
        Для Позиция = 1 По СтрДлина(Ожидаемые) Цикл
            Кандидат = Сред(Ожидаемые, Позиция, 1);
            Если Шаблон.Имя = ИмяШаблона85(Кандидат) Тогда
                Слот = Кандидат;
            КонецЕсли;
        КонецЦикла;
        Если Слот = "" Или Встреченные.Получить(Слот) <> Неопределено Тогда
            ВызватьИсключение "Чужой или повторный шаблон запрещён";
        КонецЕсли;
        ПроверитьШаблон85(Шаблон, Слот);
        Встреченные.Вставить(Слот, Истина);
    КонецЦикла;
    Для Каждого Слот Из СтрРазделить("A,B", ",") Цикл
        Найденный = ШаблоныНастроекВторогоФактораАутентификации.НайтиПоИмени(ИмяШаблона85(Слот));
        Если СтрНайти(Ожидаемые, Слот) > 0 Тогда
            ПроверитьШаблон85(Найденный, Слот);
        ИначеЕсли Найденный <> Неопределено Тогда
            ВызватьИсключение "Отсутствующий по whitelist шаблон найден в свежем поиске";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Функция ПоказатьЧерновики85(ОжидаемыйUUID) Экспорт
    Если ТипЗнч(ОжидаемыйUUID) <> Тип("Строка") Или Паспорт85() <> ОжидаемыйUUID Тогда
        ВызватьИсключение "Собственный фактический UUID пользователя изменился";
    КонецЕсли;
    СверитьХранилище85("");
    Менеджер = ШаблоныНастроекВторогоФактораАутентификации;
    Если ТипЗнч(Менеджер) <> Тип("МенеджерШаблоновНастроекВторогоФактораАутентификации") Тогда
        ВызватьИсключение "Нужен настоящий native manager, не Новый и не структура";
    КонецЕсли;
    Черновики = Новый Массив;
    Черновики.Добавить(СоздатьСвойШаблон85("A"));
    Черновики.Добавить(СоздатьСвойШаблон85("B"));
    Вывод = "Собственный local preview; не аутентификация и не вызов провайдера:";
    ЧислоСтрок = 0;
    Для Каждого Шаблон Из Черновики Цикл
        ЧислоСтрок = ЧислоСтрок + 1;
        Слот = Сред("AB", ЧислоСтрок, 1);
        ПроверитьШаблон85(Шаблон, Слот);
        Вывод = Вывод + Символы.ПС + Шаблон.Имя
            + "; " + Шаблон.МетодHTTPЗапросаНаАутентификацию + " " + Шаблон.HTTPЗапросНаАутентификацию.АдресРесурса
            + "; " + Шаблон.МетодHTTPЗапросаНаПроверкуРезультатаАутентификации + " " + Шаблон.HTTPЗапросНаПроверкуРезультатаАутентификации.АдресРесурса;
    КонецЦикла;
    Если ЧислоСтрок <> 2 Тогда
        ВызватьИсключение "Consumer должен прочитать два actual native черновика";
    КонецЕсли;
    Если Паспорт85() <> ОжидаемыйUUID Тогда
        ВызватьИсключение "Контекст пользователя изменился после просмотра";
    КонецЕсли;
    СверитьХранилище85("");
    Возврат Вывод + Символы.ПС + "Строк=2; сохранённых шаблонов=0. Все имена/методы/URI/заголовки/тела проверены, запросы не отправлялись.";
КонецФункции
Полный модуль собственной общей управляемой формы

ОбщаяФорма.ШаблоныМФА85.Модуль

Толстый управляемый клиент: команды1, ПриОткрытии1; сервер формы: ПриСозданииНаСервере2. RPC только строки/Булево.

&НаКлиенте
Перем Остановлен85;

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ПаспортUUID85 = МФА85Черновики.Паспорт85();
    Текст85 = "Сначала только собственный preview. Согласие на запись/удаление выключено.";
    Согласие85 = Ложь;
    Шаг85 = "saveA";
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Если Остановлен85 <> Неопределено Тогда
        ВызватьИсключение "Повторная инициализация не снимает СТОП";
    КонецЕсли;
    Остановлен85 = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура Просмотр85(Команда)
    Если Остановлен85 <> Ложь Тогда
        ВызватьИсключение "СТОП: не повторяйте неизвестный опыт";
    КонецЕсли;
    Остановлен85 = Истина;
    Попытка
        Итог = МФА85Черновики.ПоказатьЧерновики85(ПаспортUUID85);
        Если ТипЗнч(Итог) <> Тип("Строка") Тогда
            ВызватьИсключение "RPC должен вернуть только собственный текст, не native объекты";
        КонецЕсли;
        Текст85 = Итог;
        Остановлен85 = Ложь;
    Исключение
        Остановлен85 = Истина;
        Согласие85 = Ложь;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ОдинЭтап85(Команда)
    Если Остановлен85 <> Ложь Тогда
        ВызватьИсключение "СТОП: состояние базы нужно отдельно исследовать, не сбрасывать флаг";
    КонецЕсли;
    Если Согласие85 <> Истина Тогда
        ВызватьИсключение "Сначала прочитайте выбранный этап и явно установите согласие";
    КонецЕсли;
    Разрешение = Согласие85;
    Согласие85 = Ложь;
    Остановлен85 = Истина;
    Попытка
        Итог = МФА85Хранилище.ВыполнитьШаг85(Шаг85, Разрешение, ПаспортUUID85);
        Если ТипЗнч(Итог) <> Тип("Строка") Тогда
            ВызватьИсключение "RPC возврат или последующая проверка не завершены";
        КонецЕсли;
        Текст85 = Итог;
        Остановлен85 = Ложь;
    Исключение
        Остановлен85 = Истина;
        Согласие85 = Ложь;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Полный модуль собственного управляемого приложения

Модуль управляемого приложения своей новой CF

Толстый управляемый клиент, настоящее ПриНачалеРаботыСистемы0.

Процедура ПриНачалеРаботыСистемы()
    ОткрытьФорму("ОбщаяФорма.ШаблоныМФА85");
КонецПроцедуры

Разбор по шагам

  1. Проверить точный собственный File-паспорт и реальный UUID одного lab-пользователя, настройки второго фактора 0.

  2. Свежим GetTemplates/FindByName подтвердить пустое хранилище и отсутствие обоих точных имён.

  3. Создать A/B реальной фабрикой, заполнить пять native свойств и четыре полных HTTP запроса без host.

  4. Consumer читает actual имена/методы/URI/headers/bodies и выводит две строки, не заменяет объекты expected литералами.

  5. Повторно подтвердить собственный паспорт и 0 сохранённых шаблонов; ни Записать, ни Удалить в MAIN не вызываются.

Как проверить результат

  1. Два native шаблона и две строки local preview; хранилище перед/после 0.

  2. Все пять свойств, четыре URI/body и полные finite headers фактически проверены.

  3. Настройки пользователя не создаются и не записываются, запросы никуда не отправляются.

Ожидаемый результат

Реальные draft-объекты изучены в цельной ограниченной задаче; native/type/static сверка не является запуском MFA.

На что обратить внимание

  1. Шаблон HTTP-запроса не является отправкой.

  2. Порядок returned GetTemplates не используется для распознавания A/B: полный поиск по именам.

  3. Если получен Неопределено вместо body string или фабрики ожидаемого типа, СТОП.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.