Regira-Packages

Regira Security — External Identity Providers

Authentication against an external identity provider: validating bearer tokens it issued, and driving an interactive sign-in through OpenID Connect. For tokens this application issues itself, see JWT Authentication.


External Bearer Authentication (OIDC / Entra ID)

Validating tokens something else issued — Entra ID, Auth0, Keycloak, Duende, Okta.

AddJwtAuthentication cannot do this: it requires a Secret and always derives a symmetric key, while an external authority signs with rotating asymmetric keys published at a JWKS endpoint. AddBearerAuthentication registers no ITokenHelper — it reads tokens, it does not mint them.

var services = new ServiceCollection();
IConfiguration configuration = new ConfigurationManager();

// Any OpenID Connect provider
services.AddBearerAuthentication(o =>
{
    o.Authority = "https://your-tenant.eu.auth0.com/";
    o.Audience  = "https://api.example.com";
});

// Entra ID, from the app registration
services.AddEntraIdBearer(o =>
{
    o.TenantId = configuration["Authentication:EntraId:TenantId"]!;
    o.ClientId = configuration["Authentication:EntraId:ClientId"]!;
});

BearerValidationOptions

Property Type Default Description
AuthenticationScheme string "Bearer"  
Authority string? null Issuer base URL; signing keys discovered and refreshed from it
MetadataAddress string? null Overrides the derived metadata URL
Secret string? null Shared symmetric key, for an HMAC-signing issuer
Audience / Audiences   null Audiences wins when both are set
ValidIssuers ICollection<string>? null Null ⇒ the discovery document’s issuer
RequireHttpsMetadata bool true  
SaveToken bool false Keep the raw token for a downstream call
ValidateLifetime bool true  
ClockSkew TimeSpan Zero  
NameClaimType / RoleClaimType string "name" / "role"  
Claims ClaimNormalizationOptions (defaults)  
Configure Action<JwtBearerOptions>? null Applied before the normalization hook is chained on

Exactly one source of signing keys is required — Authority/MetadataAddress or Secret. Both, or neither, throws at registration.

EntraIdOptions

Property Type Default Description
TenantId string (required) Directory id, or organizations / common
ClientId string (required) This API’s application id
Instance string https://login.microsoftonline.com Sovereign clouds differ
UseV2Endpoint bool true  
Audiences ICollection<string>? null Defaults to both api://{ClientId} and {ClientId}
AuthenticationScheme string "Bearer"  
SaveToken bool false  
Claims ClaimNormalizationOptions (defaults)  
Configure Action<JwtBearerOptions>? null  

Entra notes

What these presets do not do

No Microsoft.Identity.Web, no MSAL. They protect an API and sign users in, and stop there — no on-behalf-of flow, no downstream calls as the user, no MSAL token cache, no incremental consent, no B2C user flows. Take Microsoft.Identity.Web directly if you need those.


Interactive Sign-in (OpenID Connect)

Signing users in through a browser: authorization code + PKCE, landing in a cookie session. Always a pair of schemes — the OIDC handler runs the challenge and code exchange, a cookie holds the session — and AddOidcAuthentication registers both.

var services = new ServiceCollection();
IConfiguration configuration = new ConfigurationManager();

// Entra ID
services.AddEntraIdSignIn(o =>
{
    o.TenantId     = configuration["Authentication:EntraId:TenantId"]!;
    o.ClientId     = configuration["Authentication:EntraId:ClientId"]!;
    o.ClientSecret = configuration["Authentication:EntraId:ClientSecret"]!;
});

// Any OpenID Connect provider
services.AddOidcAuthentication(o =>
{
    o.Authority    = "https://your-tenant.eu.auth0.com/";
    o.ClientId     = "…";
    o.ClientSecret = "…";
});

Scheme pairing

Default Scheme
DefaultScheme / DefaultAuthenticateScheme / DefaultSignInScheme the cookie
DefaultChallengeScheme / DefaultSignOutScheme the OIDC scheme

Backwards, an [Authorize] endpoint either tries to validate an id_token it does not have, or redirects to the provider on every request.

OidcAuthOptions

Property Type Default Description
AuthenticationScheme string "OpenIdConnect"  
SignInScheme string? null Defaults to Cookie’s scheme
Authority / ClientId string (required)  
ClientSecret string? null Required for the confidential-client code exchange
ResponseType string "code"  
Scopes ICollection<string> openid profile email Replaces the handler’s defaults
CallbackPath string /signin-oidc Must match a registered redirect URI exactly
SignedOutCallbackPath string /signout-callback-oidc  
SignedOutRedirectUri string? null  
UsePkce bool true  
SaveTokens bool false Keeps the tokens in the cookie — and enlarges it
GetClaimsFromUserInfoEndpoint bool true A lean id_token usually omits email
RequireHttpsMetadata bool true  
NameClaimType / RoleClaimType string "name" / "role"  
ValidIssuers ICollection<string>? null Null ⇒ the discovery document’s issuer
Cookie CookieAuthOptions (defaults) The session half
Claims ClaimNormalizationOptions (defaults)  
Configure Action<OpenIdConnectOptions>? null Applied before the normalization hook is chained on

EntraIdSignInOptions is the preset — TenantId, ClientId, ClientSecret, Instance, UseV2Endpoint, Scopes, the callback paths, SaveTokens, and a Configure reaching the full OidcAuthOptions.

OIDC notes

The code exchange itself needs a live provider — verify the full round trip against a real tenant.


Overview

  1. Index — Overview, projects, and choosing a scheme
  2. Encryption & Hashing — Symmetric encryption, PBKDF2 and BCrypt password hashing
  3. JWT Authentication — Self-issued bearer tokens, claims, and refresh tokens
  4. API Key Authentication — Key-based auth for machine callers
  5. External Identity Providers — Validating external bearer tokens; OpenID Connect sign-in
  6. Cookie Authentication — Cookie-backed sessions
  7. Composing Multiple Schemes — Running several schemes side by side
  8. Pre-built Auth Controllers — Account, password and user endpoints
  9. Practical Examples — Complete implementation examples

License

Apache License 2.0 — this package contains no license validation and no runtime limits. See LICENSE. A few companion packages are commercially licensed with a free tier; see the licensing overview.