Lyo.Authentication.OpenIdConnect
1.0.6
dotnet add package Lyo.Authentication.OpenIdConnect --version 1.0.6
NuGet\Install-Package Lyo.Authentication.OpenIdConnect -Version 1.0.6
<PackageReference Include="Lyo.Authentication.OpenIdConnect" Version="1.0.6" />
<PackageVersion Include="Lyo.Authentication.OpenIdConnect" Version="1.0.6" />
<PackageReference Include="Lyo.Authentication.OpenIdConnect" />
paket add Lyo.Authentication.OpenIdConnect --version 1.0.6
#r "nuget: Lyo.Authentication.OpenIdConnect, 1.0.6"
#:package Lyo.Authentication.OpenIdConnect@1.0.6
#addin nuget:?package=Lyo.Authentication.OpenIdConnect&version=1.0.6
#tool nuget:?package=Lyo.Authentication.OpenIdConnect&version=1.0.6
Lyo.Authentication.OpenIdConnect
OpenID Connect client base for Lyo. The Lyo API is the OIDC confidential client (BFF pattern). The frontend never sees the IdP and never receives tokens by URL fragment. After a successful external login, the API either:
- issues tokens directly as JSON, for API clients calling
/auth/login/{provider}?mode=api, or - mints a single-use handoff code and 302-redirects the browser to a whitelisted consumer origin, which then exchanges that code server-to-server for the tokens, for browser clients viaLyo.Authentication.Client.
Examples
Register services
services.AddLyoOpenIdConnect(builder.Configuration);
services.AddGoogleProviderFromConfiguration(builder.Configuration);
services.AddKeycloakProviderFromConfiguration(builder.Configuration);
Building blocks
IOpenIdConnectProvider.Abstraction describing a provider: discovery URL, client id/secret, scope/claim mapping.OpenIdConnectProviderRegistry.Keyed by name, resolved at/auth/login/{name}.OidcDiscoveryCache.Hourly-refreshed OpenID Configuration cache.OidcJwksResolver.Fetches and caches the provider's JWKS forid_tokensignature verification.PkceCodes+StateNonceProtector.Generate and seal PKCE/state/nonce in an HTTP-only cookie viaIDataProtector.OidcAuthorizationUrlBuilder.Composes the/authorizeURL withcode_challenge,state,nonce.OidcTokenExchangeClient.TypedHttpClientthat POSTs the authorization code back for tokens.OidcIdTokenValidator.Validates issuer, audience, nonce, exp, signature.IExternalLoginCoordinator/DefaultExternalLoginCoordinator.Wraps the whole flow: discover-or-link-or-create the Lyo user, refreshlinked_identity.scopes_json, and callILyoJwtIssuer.IssueAsync. EmitsAuthAuditEventKind.{ExternalLoginSucceeded,ExternalLoginRejected,UserProvisioned,IdentityLinked}along the way.IHandoffCodeStore/InMemoryHandoffCodeStore.Single-use, TTL-bounded handoff codes (browser handoff path).
Endpoints
app.MapLyoAuthEndpoints() wires:
| Method | Path | Purpose |
|---|---|---|
| GET | /auth/login/{provider}?returnUrl=...&mode=browser|api |
Starts the OIDC login. mode=browser or mode=api. |
| GET | /auth/callback/{provider} |
IdP redirects back here. Browser mode mints a handoff code and 302s to {returnUrl}?lyo_handoff=lyoh_.... API mode returns 200 OK with {access_token, refresh_token, expires_in, token_type}. |
| POST | /auth/handoff/exchange |
Body { code }. Consumes a handoff code once, returns tokens. Audited as HandoffCodeConsumed / HandoffCodeRejected. |
| POST | /auth/token |
Reserved for first-party API client grants. |
| POST | /auth/refresh |
Body { refresh_token }. Returns a rotated {access_token, refresh_token, expires_in}. |
| POST | /auth/logout |
Body { refresh_token }. Revokes the token; audited as TokenRevoked + SignedOut. |
| GET | /auth/me |
Returns the principal for the bearer access token. |
| GET | /auth/users/{id} |
Returns the same shape as /auth/me for an arbitrary user id. Requires the auth.users.read scope (policy scope:auth.users.read). Scopes reflects the target user's baseline scopes, not the caller's. |
Registration
That call binds two option sections. LyoExternalLogin sets Sealing.{Purpose,DefaultExpiration} and the cookie name for the PKCE/state envelope. LyoOidcBff is documented under BFF options below. The per-provider packages register their IOpenIdConnectProvider implementation under their canonical name (google, keycloak:<realm>).
BFF options
{
"LyoOidcBff": {
"AllowedReturnOrigins": [ "http://localhost:5138", "https://app.example.com" ],
"DefaultReturnUrl": "/",
"HandoffCodeTtl": "00:00:30"
}
}
AllowedReturnOrigins.Exact origin (scheme://host[:port]) match for absolutereturnUrlvalues andOriginchecks on/auth/handoff/exchange. Same-origin relativereturnUrlstarting with/is always allowed. Anything outside the allowlist falls back toDefaultReturnUrl.DefaultReturnUrl.Used whenreturnUrlis missing or rejected.HandoffCodeTtl.Short. 30s is plenty. The consumer redeems immediately on the redirect.
Auditing
Every meaningful state transition emits an AuthAuditEvent. With Lyo.Authentication.Postgres wired up these land in [user].[event]. The kind column stores the enum's string name, JwtIssued, HandoffCodeIssued, and so on. Otherwise they hit whatever IAuthAuditRecorder is registered, default NullAuthAuditRecorder. IP, User-Agent, and correlation come from the registered IAuthAuditContextAccessor. Call services.AddLyoApiTokenAuthentication() or services.AddLyoAuthHttpContextAccessor() standalone on an ASP.NET host to swap in HttpAuthAuditContextAccessor.
| Kind | When |
|---|---|
ExternalLoginSucceeded |
Callback validated, tokens minted. |
ExternalLoginRejected |
State/nonce/signature/policy failure. Carries a stable reason. |
UserProvisioned |
First-time JIT user creation. |
IdentityLinked |
New (provider, subject) linked to a user. |
HandoffCodeIssued |
Mint succeeded; included in the browser redirect. |
HandoffCodeConsumed |
Successful /auth/handoff/exchange. |
HandoffCodeRejected |
Wrong origin, expired, unknown, or already consumed. |
JwtIssued |
Access token minted. |
RefreshSucceeded / RefreshRejected |
/auth/refresh outcome. |
TokenRevoked / SignedOut |
/auth/logout outcome. |
Talking to it
- Browser consumers. Use
Lyo.Authentication.Clientfor handoff redemption, the session cookie, andLyoAuthDelegatingHandlerfor outbound refresh. - API clients. Call
/auth/login/{provider}?mode=apiand consume the JSON token response directly. Call/auth/refreshwhen the access token nears expiry.
Dependencies
Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).
Lyo.Api.Models(direct, lyo)Lyo.Authentication(direct, lyo)Lyo.Common(direct, lyo)Lyo.Exceptions(direct, lyo)BouncyCastle.Cryptography2.6.2(direct, third-party)Lyo.Authentication.Models(transitive, lyo)Lyo.DateAndTime(transitive, lyo)Lyo.Hashing(transitive, lyo)Lyo.KeyStore(transitive, lyo)Lyo.Query.Models(transitive, lyo)Lyo.Result(transitive, lyo)Konscious.Security.Cryptography.Argon21.3.1(transitive, third-party)Microsoft.Bcl.AsyncInterfaces10.0.5(transitive, microsoft, netstandard2.0)Microsoft.Extensions.Configuration.Binder10.0.5(transitive, microsoft)Microsoft.Extensions.DependencyInjection.Abstractions10.0.5(transitive, microsoft, net10.0, netstandard2.0)Microsoft.Extensions.Hosting.Abstractions10.0.5(transitive, microsoft)Microsoft.Extensions.Logging.Abstractions10.0.5(transitive, microsoft)Microsoft.Extensions.Options10.0.5(transitive, microsoft)System.IO.Hashing10.0.5(transitive, microsoft, net10.0)System.Memory4.6.3(transitive, microsoft, netstandard2.0)System.Text.Json10.0.5(transitive, microsoft, netstandard2.0)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- BouncyCastle.Cryptography (>= 2.6.2)
- Lyo.Api.Models (>= 1.0.6)
- Lyo.Authentication (>= 1.0.6)
- Lyo.Common (>= 1.0.6)
- Lyo.Exceptions (>= 1.0.6)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Lyo.Authentication.OpenIdConnect:
| Package | Downloads |
|---|---|
|
Lyo.Authentication.Google
Google OpenID Connect provider profile for Lyo.Authentication. Adds AddGoogleProvider to wire Google as a registered IdP for the BFF login flow, with optional Google Workspace hosted-domain enforcement (the hd claim). |
|
|
Lyo.Authentication.Keycloak
Keycloak OpenID Connect provider profile for Lyo.Authentication. Adds AddKeycloakProvider to wire one or more Keycloak realms as IdPs for the BFF login flow, with realm-role to Lyo-scope mapping. |
|
|
Lyo.Config.Api
Central HTTP API exposing Lyo.Config PostgreSQL-backed IConfigStore for microservices (polling-friendly ETags). Embed via AddConfigApi / MapConfigApiEndpoints. |
GitHub repositories
This package is not used by any popular GitHub repositories.