Хотите вовсе не тянуть Veriqa в свою сборку? Тот же сервер работает и отдельно, а приложение
общается с ним по обычному OIDC — в облаке, в Docker или службой ОС; ни одного пакета Veriqa в
дереве зависимостей и в SBOM. Что это меняет для .NET-клиента —
если Veriqa работает отдельно.
В примерах — плейсхолдеры (
my-app, токены ботов). Подставьте свои значения и никогда не
коммитьте реальные секреты: держите их в user-secrets в разработке и в секрет-сторе в
продакшне.1. Установите пакеты
2. Зарегистрируйте сервисы
AddVeriqaAuthServer читает конфигурацию из стандартного IConfiguration хоста. Внутри вы
выбираете хранилище OpenIddict, настраиваете хранилище транзакций и подключаете нужные каналы.
Program.cs
"Enabled": true) — иначе регистрируются лишь опции и
валидатор.
3. Соберите middleware pipeline
Program.cs
Эндпоинты Email-канала (magic link и письмо в один тап)
MapVeriqaAuthServer мапит автоматически —
но только когда канал включён в конфигурации (Veriqa:Channels:Email:Enabled: true). Отдельный
вызов не нужен.wwwroot/locales необязателен: без него сообщения каналов уходят на базовом языке, и
предупреждение на старте Locale files directory not found … ожидаемо. Переводить вручную ничего не
нужно: готовые локали (en, ru, zh, pseudo) поставляются пакетом
Veriqa.Core.ChannelLocales — как их подключить, описано в
Локализации. Так же ожидаемо на дефолтной конфигурации
Initiator context geolocation is enabled but the GeoIP provider is unavailable: вход работает, просто
гео-поля контекста инициатора остаются пустыми. В Development после старта идут ещё несколько десятков
диагностических строк info о разрешённой конфигурации — это нормально.
4. Настройте конфигурацию
Секреты каналов и OIDC-клиенты задаются в конфигурации. Всё, что принадлежит Veriqa, живёт под корневым ключомVeriqa: секции каналов — под Veriqa:Channels, настройки auth-сервера —
рядом с ними в том же разделе.
appsettings.json
Две последние секции — то, что пользователь читает по завершении входа.
Channels:OutcomeNotice:DisplayIntent задаёт, где появляется квитанция исхода: ReplacePrompt —
поставочное значение, выписанное здесь явно, чтобы настройка была видна, — ставит квитанцию на
место сообщения с вопросом, а NewMessage оставляет вопрос в переписке и добавляет отдельное
сообщение. Это намерение, а не обещание: Telegram и MAX его исполняют, WhatsApp всегда шлёт новое
сообщение, а Email квитанцию исхода не показывает вовсе.MessageTemplates задаёт формулировки этих квитанций. Продукт везёт свои по адресу
ByType:login:BySurface:…, а уровень перебирает все шаги адреса прежде, чем резолюция спустится
на уровень ниже, — поэтому переобъявление достигается только по тому же адресу, отсюда и
глубина Templates выше. {app} — серверный слот: для входа это DisplayName клиента. Последний
шаг каждой лестницы не пользуется слотами, потому что ни один слот квитанции не гарантирован.
Полные правила — в Справочнике конфигурации.WhatsApp работает через официальный Meta Cloud API (
Provider: MetaCloudApi);
BusinessPhoneNumber — в формате E.164 для deep link. Подключайте только используемые каналы —
секция без "Enabled": true канал не активирует, поэтому две секции выше показаны выключенными, а
не убраны. Полная настройка Email (SMTP для Pull и inbound для Push) — в
Настройке каналов.redirect_uri сверяется с AllowedRedirectUris точным совпадением — wildcard не
поддерживаются. Валидатор при старте требует абсолютные URI; в продакшне используйте https
(http — только для loopback-адреса, например localhost или 127.0.0.1, в разработке).
5. Подключите клиентское приложение
Всё, что выше, — сторона issuer’а. Клиент, который в него входит, — обычный OIDC Relying Party: ничего специфичного для Veriqa в нём нет, это та же обвязка, что вы написали бы для любого OpenID Connect провайдера. В ASP.NET Core эта обвязка приезжает одним пакетом:Program.cs (клиентское приложение)
Challenge — на страницу Veriqa с QR и
кнопками каналов:
Program.cs (клиентское приложение)
dotnet new web выдаёт каждому проекту случайные порты, поэтому из коробки ни Authority, ни
redirect_uri не указывают на запущенный процесс — шаг 10 поднимает оба
на адресах, использованных здесь.
Клиент
my-app из шага 4 задан без ClientSecret — значит, он публичный, и Veriqa требует
от него PKCE (S256). Поэтому UsePkce = true, а ClientSecret не задаётся. Для
конфиденциального клиента секрет прописывается с обеих сторон.6. Разберитесь в потоке входа
Пользователь начинает транзакцию на десктопе и подтверждает её в доверенном канале на телефоне. Veriqa отслеживает транзакцию и только потом отдаёт выпуск результата OpenIddict.7. Эндпоинты
MapVeriqaAuthServer мапит стандартный OIDC-контракт и служебные эндпоинты:
Эндпоинты Email-канала мапятся тем же
MapVeriqaAuthServer автоматически — только при
включённом канале (Veriqa:Channels:Email:Enabled: true):
8. Claims пользователя
Итоговый набор claims формирует маппер по умолчанию из завершённой транзакции:picture приходит, только когда выполнены все три условия: клиент запрашивает scope avatar
(options.Scope.Add("avatar")), scope разрешён в AllowedScopes клиента и включён
GetClaimsFromUserInfoEndpoint = true — в id_token аватар не попадает никогда, его отдаёт только
userinfo. Как его забрать, не раздувая cookie, — см.
OIDC + Veriqa: разбор.
Маппинг переопределяется своим IClaimsMapper — см. Настройку и кастомизацию.
9. Выбор канала через acr_values
Клиент может ограничить вход конкретным каналом через стандартный OIDC-параметрacr_values
формата channel:{тип}:
channel:telegram channel:whatsapp) — пользователь выбирает из
перечисленных. Без параметра доступны все включённые каналы.
10. Контрольная точка
Поднимите оба процесса на адресах, которых ждёт конфигурация: issuer — на порту изAuthority,
клиент — на порту своего redirect_uri:
applicationUrl файла Properties/launchSettings.json каждого
проекта. Клиент сам ходит к issuer’у по https, поэтому dev-сертификат ASP.NET Core должен
существовать и быть доверенным: создайте его командой dotnet dev-certs https, затем доверьте
командой dotnet dev-certs https --trust. На Linux команда доверия тоже работает и печатает значение
SSL_CERT_DIR, которое нужно выставить; строка
There was an error trusting the HTTPS developer certificate., которой она заканчивается, там
ожидаема и провала шага не означает — экспортируйте напечатанное значение, оставив в списке
каталог сертификатов вашего дистрибутива, иначе перестанут проверяться чужие цепочки (restore с
nuget.org, любые исходящие HTTPS-вызовы):
openssl version -d печатает OPENSSLDIR — каталог конфигурации OpenSSL, а не сами
сертификаты, — а файлы CA с hash-ссылками, по которым OpenSSL и ищет, лежат в его подкаталоге
certs, отсюда /certs на конце. На Debian и Ubuntu получается /usr/lib/ssl/certs, на других
дистрибутивах префикс другой — поэтому он читается, а не выписывается. После этого сертификат
доверен. Подробности — в разделе «Trust HTTPS certificate on Linux» статьи
Enforce HTTPS in ASP.NET Core.
1
Запустите приложение
Поднимите оба процесса, как показано выше, и откройте клиента по адресу
https://localhost:7020.2
Запустите поток
Выберите «Войти через Veriqa» и отсканируйте QR доверенным каналом на телефоне. У Email QR
есть в режиме Push; в режиме Pull вместо него — поле адреса и кнопка «Get a link».
3
Подтвердите на телефоне
Подтвердите запрос в MAX / Telegram / WhatsApp / другие мессенджеры / Email. Десктоп обновит
статус по SignalR или polling.
4
Подтвердите на десктопе
У Email — и у любого канала при
Veriqa:LoginConfirmation:Mode = OnWebPage — страница входа
затем спрашивает ещё раз: подтвердите вход там.5
Проверьте результат
Убедитесь, что вы вошли и ожидаемые claims на месте.
Если Veriqa работает отдельно
Всё выше — встроенный режим: Veriqa живёт пакетами внутри вашего хоста. Тот же сервер может работать и отдельно, а приложение входит в него по обычному OIDC — облако Veriqa, ваш контейнер Docker или служба (systemd либо служба Windows) на вашей машине. Для .NET-приложения это меняет дерево зависимостей, а не код: остаётся клиентская половина шага 5, а все пакеты Veriqa уходят — ни один компонент Veriqa не попадает в вашу сборку и в SBOM.Veriqa Cloud сейчас недоступен — строка про облако ниже описывает контракт его API.
Используйте self-hosted; подробности — в Veriqa Cloud.
Обвязка — та же, что в шаге 5, с одним отличием: адрес
issuer’а берётся из конфигурации, а не из кода, потому что это единственное значение, которое
меняется между режимами и между окружениями.
Program.cs (клиентское приложение)
appsettings.json (клиентское приложение)
options.ClientSecret — из user-secrets в разработке и из
секрет-стора в продакшне, но не из appsettings.json. В облаке секрет выдаётся отдельным явным
действием на экране Applications и показывается один раз.
Больше ничто на этой странице от режима не зависит: эндпоинты шага 7, claims
шага 8 и ограничение канала через acr_values
(шаг 9) — это поведение issuer’а, и клиент видит его через
discovery, в каком бы режиме тот ни работал.
Как именно поставлен отдельный сервер — следующий выбор, и на клиентскую сторону он не влияет:
контейнер Docker — быстрый старт self-hosted — либо архив, который
ставится юнитом systemd или службой Windows, без Docker и без рантайма .NET на машине —
установка службой ОС.
Дальше
Настройка и кастомизация
Дизайн страницы входа, локализация, точки расширения.
Hardening к продакшну
Что проверить перед выпуском в продакшн.
OIDC + Veriqa: разбор
Где Veriqa встаёт в стандартный OIDC-поток.
Архитектура
Строительные блоки коннектора.
Veriqa отдельным сервером
Тот же issuer вне вашей сборки — в Docker или службой ОС.