OIDC on one screen
OpenID Connect is a thin identity layer on top of OAuth 2.0. The application receives two tokens: anid_token (who the user is) and an access_token (access to APIs). The app does
not check passwords itself — it trusts the issuer (authorization server), which returns
signed tokens.
Authorization Code Flow + PKCE
The standard secure flow for web and desktop apps:- The app redirects the user to the issuer’s
/authorize(withstate,nonceand PKCE parameters). - The user authenticates on the issuer side.
- The issuer returns a short-lived
codeto the registeredredirect_uri. - The app exchanges the
code(+ PKCEcode_verifier) for tokens at/token.
S256 method is mandatory for public clients — it protects the code exchange
from interception.
Where Veriqa fits
Veriqa sits between steps 2 and 3 — in place of “the user authenticates”. Instead of a sign-in form, the issuer opens a Veriqa transaction: it shows a QR code / entry point, waits for confirmation in a trusted channel, builds aClaimsPrincipal from the result and hands it to
OpenIddict to issue the code. From there it is plain OIDC (code → /token → tokens).
The full flow, step by step
From starting the transaction to issuing OpenIddict tokens.
The channel adapter in the flow
The channel adapter (Telegram / WhatsApp / other channels / Email) links the transaction to a specific messaging app: it delivers the confirmation request to the user, receives their response and returns the resolved identity to the transaction. Each channel is a separate adapter, and the set is extensible.Resolved identity and claims
After confirmation Veriqa builds an identity snapshot and maps it to OIDC claims:channel is a Veriqa-specific scope and it is the gate for the channel claims. If you do not request
it, neither claim reaches the access_token, the id_token or the /connect/userinfo response.
Add channel to your RP’s requested scopes and to the client’s AllowedScopes if your application
reads them.
avatar is the other Veriqa-specific scope, and it is the gate for picture. The value is the image
itself, a data:image/…;base64,… URI (a channel that exposes a public link may give an https
URL instead). It travels only in the access_token and so reaches you only through
/connect/userinfo; it is never put into the id_token. Request avatar (and add it to the
client’s AllowedScopes), fetch the claims from userinfo (GetClaimsFromUserInfoEndpoint = true in
ASP.NET Core), and treat a missing picture as “no avatar”. In ASP.NET Core picture is not mapped
into the principal by default, and it should not be: a data URI in the authentication cookie inflates
the request headers. Take the image from the userinfo JSON in OnUserInformationReceived and keep it
in your own store.
/connect/userinfo returns only the claims permitted by scopes and configuration. Override the
mapping with your own IClaimsMapper.
Step-up and confirmation in OIDC terms
2FA and step-up are not separate transaction types but overlays: 2FA over login,
step-up over confirmation. It is the same Veriqa transaction model with extra context, so
confirming a sensitive action goes through the same trusted channel as a normal sign-in.
What Veriqa is NOT
Veriqa is an OpenID Connect provider, but not an IAM: it does not store or manage user accounts. Veriqa adds a sign-in method and channel linking to your system, and the user base stays with you.Further reading
.NET quickstart
Wire Veriqa into an ASP.NET Core host.
Preparing for production
The pre-production checklist.