Releases: Abblix/Oidc.Server
Release list
v2.3
⚠️ Breaking Changes
Upgrading from 2.2 needs action in a few areas — see Breaking Changes in the README for migration steps.
- Implicit Flow is opt-in: implicit and hybrid response types are rejected at client registration until the host enables them explicitly.
- Dynamic Client Registration requires an Initial Access Token by default; anonymous registration is rejected unless the requirement is turned off.
- Dynamic Client Registration rejects a back-channel logout endpoint that violates the outbound-request security policy (non-secure scheme, internal host, or private address) under the secure defaults.
- Authorization success and error responses now flow through a single formatting interface; hosts that customized error-response formatting must re-point to it.
🚀 Features
- Rich Authorization Requests (RFC 9396) (#135)
- Token Exchange (RFC 8693) (#135)
- JWT Secured Authorization Response Mode, JARM (specification) (#172)
- JWT Response for OAuth Token Introspection (RFC 9701) (#177)
- Certificate-bound access token verification (RFC 8705 §3) (#159)
- JWE-encrypted request objects (RFC 9101 §6.1) (#171)
- Signed authorization server metadata (RFC 8414 §2.1) (#127)
- Client key set binding from configuration (#115)
- DPoP sender-constrained tokens (RFC 9449) (#100, #112)
- Token type header pinning (RFC 8725 §3.11) (#80, #93)
- JOSE critical header parameter handling (RFC 7515 §4.1.11) (#75, #88, #134)
- Implicit Flow opt-in (#90, #91)
- Initial Access Token for Dynamic Client Registration (RFC 7591 §3)
- Dynamic Client Registration scope, software identifier, and software statement metadata (RFC 7591)
- Structured logging via a source generator
✏️ Improvements
- Unified client-addressed JWT signing and encryption path (#177)
- JOSE critical-header extension point reshaped to keyed-name dependency injection (#146, #148, #151)
- Host pre-registrations win the dependency-injection resolution race
- Thread-safe client-information storage
- JWT validation returns errors instead of throwing on unsupported algorithm or key combinations
- Base64URL handling migrated to the runtime primitive (#79, #89)
- Flow-type validation simplified with a filter chain (#92)
- Server-side gRPC stack removed in favour of the Protocol Buffers runtime (#68)
- Granular JWS key-resolution diagnostics (RFC 7515 §4.1.4 / §6) (#84, #97)
- Typed accessors for JWS header parameters (RFC 7515 §4.1.2 to §4.1.8) (#81, #94)
- JWS verification key pinned to its declared algorithm (RFC 7517 §4.4) (#78, #87)
- HMAC key length enforced (RFC 7518 §3.2) (#77, #86)
- Pairwise subject identifier derivation hardened to HMAC
- Authorization-response issuer parameter advertised in discovery (RFC 9207)
- Test suite parallelized via assembly fixtures and an RFC-concern split (#157)
- Migration to xunit v3 on Microsoft Testing Platform (#63)
- Testing-Platform-native test-report upload (#95)
- Central Package Management with transitive pinning (#95)
- Migration to the XML solution format with local Sonar analysis
🛠 Fixes
- Device Authorization Grant hardening (RFC 8628) (#165)
- CIBA hardening: single-use authentication request identifier, push-delivery integrity, HTTPS notification endpoint (#166, #158)
- Client authentication: constant-time secret comparison and a required unique identifier on client assertions (#163)
- Enforce the client scope set, require an expiration on JWT-bearer assertions, validate resource configuration (#167)
- Preserve allowed scopes and software identifier and version on client update (#168)
- Enforce client metadata: default maximum authentication age, default authentication context, token-endpoint authentication algorithm, UserInfo encryption (#169)
- Pin the request-object and backchannel-authentication request signing algorithms to the registered values (#170)
- Validate the encrypted-response algorithm and encryption metadata in Dynamic Client Registration (#174)
- Token Exchange identity-token origin bound through audience and authorized party (#175)
- Omit the scope from the authorization callback on pure code flow (#124)
- Pushed Authorization Requests: request reference not consumed at fetch time, JSON error instead of a redirect to login (#123, #119)
- Graceful JWT validation errors for a missing key resolver and an empty pre-bound key set (#120, #121, #122)
- CORS enabled on discovery endpoints
- Protected-resource error responses aligned with RFC 6750 and RFC 9110
- Dynamic Client Registration key-set and software-statement validation hardened
- Flaky CI failures from parallelized suites (#161)
- Pushed Authorization Requests: the request reference is now strictly single-use — consumed once an authorization code or token is issued, so it cannot be replayed within its time-to-live (RFC 9126 §6)
- Back-channel logout notifications are now reliably delivered and awaited, with per-client failure isolation so an unreachable client endpoint cannot fail the end-user's logout
- Implicit Flow response-builder dependency lifetimes corrected so the feature's components resolve consistently
Detailed Description
Rich Authorization Requests (RFC 9396)
- The authorization and token endpoints now accept fine-grained, transaction-level authorization details per RFC 9396, so a client can request specific permissions instead of coarse scopes. Each authorization detail is validated by a handler selected on its type, consented through a host-provided descriptor, and carried end-to-end into the access token and, optionally, the identity token. The flow is wired through the authorization endpoint, Pushed Authorization Requests, the token endpoint, CIBA, and the device authorization grant. The supported detail types are advertised in discovery.
Token Exchange (RFC 8693)
- A new token-exchange grant implements RFC 8693 for both impersonation and delegation. The handler resolves several subject- and actor-token formats, builds the delegation chain, and enforces a per-client allow-list of subject-token typ...
v2.2
🚀 Features
- JWT implementation based on .NET built-in
System.Text.Json.Nodesobject model (RFC 7515, RFC 7516) (#39) - JWE algorithm support:
RSA-OAEP-256, AES-GCM key wrapping, direct key agreement (RFC 7518) - ACR values support and AMR compliance (RFC 8176) (#40)
- CSP nonce support for front-channel logout and session management
✏️ Improvements
- Template-based rendering for front-channel logout pages
- Configurable
Pathparameter for OIDC Session Management cookie - Operation capability validation for
JsonWebKeyclasses - Interoperability tests between Abblix JWT and
Microsoft.IdentityModel.Tokens - Symbol package (
.snupkg) publishing for improved debugging
🛠 Fixes
- JWT audience validation for token endpoint and issuer
- Dynamic client registration JWKS validation
- SSRF handler lifetime causing shared handler disposal errors
Detailed Description
JWT implementation based on .NET built-in System.Text.Json.Nodes object model (RFC 7515, RFC 7516)
- Complete JWT signing and encryption infrastructure written from scratch, replacing
Microsoft.IdentityModel.Tokensin production code. Uses modernJsonObject-based programming model fromSystem.Text.Json.Nodesdesigned specifically for JWT workflows. Provides native handling of JSON types (numbers, arrays, nested objects) without string conversions, and uses .NET cryptographic primitives directly (RSA,ECDsa,AES) for simplified key management. Implements exception-free Try pattern throughout the validation pipeline for better performance.
JWE algorithm support: RSA-OAEP-256, AES-GCM key wrapping, direct key agreement (RFC 7518)
- Added
RSA-OAEP-256(RSA-OAEP with SHA-256) and AES-GCM key wrapping algorithms (A128GCMKW,A192GCMKW,A256GCMKW) that were unavailable in Microsoft's JWT library. Implemented RFC 7518 Section 4.5 direct key agreement (diralgorithm) for JWE where the Content Encryption Key is the shared symmetric key itself, eliminating key wrapping overhead.RSA-OAEP-256provides enhanced security overRSA-OAEPwith SHA-1, and AES-GCM key wrapping offers authenticated encryption with superior performance compared to AES-CBC-HMAC.
ACR values support and AMR compliance (RFC 8176)
- Added
acr_values_supportedto OpenID discovery document per RFC 8414 and introducedIAcrMetadataProviderfor configurable ACR values. Aligned Authentication Method Reference (AMR) values with RFC 8176, removing non-standard values and documenting compliance. Enables relying parties to request specific authentication assurance levels during authorization.
CSP nonce support for front-channel logout and session management
- Added Content Security Policy nonce propagation to front-channel logout iframes and check session iframe, ensuring compliance with strict CSP policies that block inline scripts. Replaced inline HTML generation with Razor template rendering for front-channel logout pages.
Interoperability tests between Abblix JWT and Microsoft.IdentityModel.Tokens
- Comprehensive bidirectional tests verifying tokens created by Abblix can be validated by
Microsoft.IdentityModel.TokensJsonWebTokenHandlerand vice versa. Covers unsigned JWTs, all signing algorithms (RSA, ECDSA, HMAC), and JWE encryption with multiple algorithm combinations. Ensures full RFC 7515/RFC 7516 compliance and compatibility with industry-standard JWT libraries.
JWT audience validation for token endpoint and issuer
- Fixed validation to accept both the token endpoint URL and the issuer identifier as valid JWT audience values per RFC 7523. Previously only one was accepted, causing authentication failures for clients using the other.
Dynamic client registration JWKS validation
- Fixed validation of JWKS (JSON Web Key Sets) provided during dynamic client registration. Previously, malformed or invalid key sets could pass without proper validation.
SSRF handler lifetime causing shared handler disposal errors
- Changed SSRF protection handler from singleton to transient lifetime in DI registration. The shared singleton instance was being disposed prematurely, causing errors in subsequent requests that reused the handler.
✅ Why It Matters
- JWT implementation eliminates the
Microsoft.IdentityModel.Tokensdependency, providing JWT-optimized architecture with native JSON types and exception-free validation - JWE algorithms enable
RSA-OAEP-256and AES-GCM key wrapping for stronger encryption and better performance - Direct key agreement (
dir) reduces computational overhead for microservices and service-to-service communication - ACR/AMR compliance ensures relying parties can request and verify specific authentication assurance levels per RFC 8176
- CSP nonce support enables deployment behind strict Content Security Policies without disabling inline script protection
- Interoperability validation provides production confidence through bidirectional compatibility with
Microsoft.IdentityModel.Tokens
What's Changed
Full Changelog: v2.1...v2.2
v2.1
🚀 Features
- ECDSA Support for JWT Signing and Encryption (RFC 7518)
- Dynamic Client Registration Management (RFC 7592)
- JWT Secured Authorization Request (RFC 9101)
🛠 Fixes
- Client Authentication Method Validation
- Request Object Lifetime Validation
- Client Jwt Validator Cache Pollution Prevention
- Malformed JWT Token Handling
Detailed Description
ECDSA Support for JWT Signing and Encryption (RFC 7518)
- Added support for Elliptic Curve Digital Signature Algorithm with ES256/ES384/ES512 signing algorithms per RFC 7518. ECDSA offers equivalent security with smaller key sizes (256-bit ECDSA ≈ 3072-bit RSA), resulting in faster cryptographic operations and smaller token sizes. Critical for mobile applications, IoT devices, and high-throughput scenarios.
Dynamic Client Registration Management (RFC 7592)
- Implements RFC 7592 with PUT operation for updating client configurations and compliant URI format for management endpoints. Includes credentials validation for registration requests and exposes
TokenEndpointAuthMethodin responses for proper authentication method discovery.
JWT Secured Authorization Request (RFC 9101)
- Implements lifetime validation per RFC 9101. Server prevents replay attacks by rejecting expired request objects based on
exp/nbfclaims. Critical for financial-grade APIs where request integrity over time is essential.
Client Authentication Method Validation
- Fixed authentication flow to validate method compatibility before attempting authentication. Now distinguishes "method not attempted" (wrong method type) from "authentication failed" (correct method, wrong credentials) for easier troubleshooting.
Request Object Lifetime Validation
- Server properly rejects expired request objects to prevent replay attacks. Added
ValidateLifetimeflag to checkexpandnbfclaims during request object validation.
Client Jwt Validator Cache Pollution Prevention
- Fixed thread-safety issue where shared mutable state in
ClientJwtValidatorcaused validation interference across concurrent requests. IntroducedValidationContextclass to ensure thread-safe concurrent validations.
Malformed JWT Token Handling
- Gracefully handles JWT tokens with out-of-range timestamps (
exp,iat,nbfexceedingDateTimeOffsetvalid range). Returns proper OIDC error responses instead of unhandled exceptions.
✅ Why It Matters
- ECDSA enables modern cryptography with smaller keys and faster operations
- RFC 7592 enables dynamic client lifecycle management for SaaS and multi-tenant deployments
- JAR lifetime validation strengthens security against replay attacks for financial-grade APIs
- Thread-safe JWT validation prevents race conditions in high-concurrency environments
What's Changed
Full Changelog: v2.0.1...v2.1
v2.0.1
🛠 Fixes
- Fixed logout failures when using ID token for authentication
Detailed Description
Fixed logout failures when using ID token for authentication
- Resolved an issue where logout requests with
post_logout_redirect_uriwere incorrectly rejected whenclient_idwas not provided, even though a validid_token_hintwas present. Per OpenID Connect specification, when an ID token hint is provided, the server can identify the client from the token itself, makingclient_idunnecessary. This fix allows users to log out successfully using their ID token for authentication without being forced to supply redundant client credentials.
What's Changed
Full Changelog: v2.0...v2.0.1
v2.0
⚙️ Platform Support
- .NET 8 (LTS), .NET 9, .NET 10 (latest)
🚀 Features
- mTLS Client Authentication (RFC 8705) - Self-signed and PKI/CA validation with certificate-bound tokens
- JWT Bearer Grant Type (RFC 7523) - Service-to-service authentication using signed JWTs for secure API-to-API communication (#38)
- Device Authorization Grant (RFC 8628) - OAuth flow for input-constrained devices (smart TVs, IoT, CLI tools) (#37)
- CIBA Ping/Push Modes & Long-Polling - Complete delivery mode implementation with ping notifications, push token delivery, and long-polling support (#36)
- client_secret_jwt Authentication - JWT-based client authentication per OIDC Core spec (#35)
- Protocol Buffer serialization - 40-60% smaller storage footprint with faster processing
- SSRF Protection - Multi-layered defense with DNS validation and IP blocking
- ECDSA Support - Enables compliance with modern security standards
✏️ Improvements
- Result Pattern Migration - Simplified codebase by eliminating many abstract response type hierarchies and boilerplate code (#34)
Detailed Description
Result Pattern Migration
- Replaced inheritance-based response type hierarchy with
Result<TSuccess, TFailure>pattern, eliminating abstract base types and dozens of boilerplate response classes. The pattern enforces explicit error handling at compile time while dramatically reducing code complexity - less boilerplate, clearer intent, and easier maintenance.
mTLS Client Authentication (RFC 8705)
- Implements mutual TLS with two authentication methods: self_signed_tls_client_auth (JWKS public key matching) and tls_client_auth (Subject DN/SAN validation). Certificate-bound tokens prevent token theft - even stolen access tokens can't be used without the matching client certificate.
JWT Bearer Grant Type (RFC 7523)
- Enables secure service-to-service authentication where client applications use signed JWTs to obtain access tokens. Critical for microservices architectures, API gateways, and machine-to-machine communication without user interaction. Supports both client assertions and JWT authorization grants with comprehensive security hardening including algorithm validation, replay protection, and maximum JWT age enforcement.
Device Authorization Grant (RFC 8628)
- Implements OAuth 2.0 flow for devices with limited input capabilities or no browser. Users authenticate on a secondary device (phone/computer) while the primary device polls for authorization. Essential for smart TVs, IoT devices, CLI tools, and gaming consoles. Includes brute force protection with exponential backoff and per-IP rate limiting.
CIBA Ping/Push Modes & Long-Polling
- Completes the CIBA implementation by adding ping mode, push mode, and long-polling support. Ping mode notifies clients at their callback endpoint when authentication completes. Push mode delivers tokens directly to client notification endpoints. Long-polling (30-second configurable timeout) holds polling requests until authentication completes, dramatically reducing server load and response latency.
client_secret_jwt Authentication
- Implements JWT-based client authentication as specified in OpenID Connect Core. Clients authenticate by creating and signing JWTs with their client secret, providing stronger authentication than HTTP Basic while supporting key rotation and enhanced security policies.
Protocol Buffer Serialization
- Binary serialization alternative with 40-60% smaller size and faster processing. Reduces Redis/cache memory consumption and network bandwidth in distributed deployments. Opt-in via DI configuration with full backward compatibility.
SSRF Protection
- Multi-layered Server-Side Request Forgery protection blocks private IP ranges (RFC 1918, RFC 4193), localhost, and prevents DNS rebinding attacks. Protects authorization servers from attackers exploiting dynamic discovery to probe internal infrastructure or access cloud metadata endpoints.
ECDSA Support
- Added support for Elliptic Curve Digital Signature Algorithm (ECDSA) certificates alongside existing RSA support. ECDSA offers equivalent security with significantly smaller key sizes (256-bit ECDSA ≈ 3072-bit RSA), resulting in faster cryptographic operations, reduced CPU usage, and smaller token sizes. Critical for mobile applications, IoT devices, and high-throughput scenarios where computational efficiency matters. Enables compliance with modern security standards that mandate or prefer elliptic curve cryptography.
✅ Why It Matters
- Certificate-based authentication enables regulatory compliance (PSD2, Open Banking, FAPI) without custom infrastructure
- JWT Bearer grants enable zero-touch service-to-service authentication for microservices
- Device flow supports modern IoT and smart device ecosystems without compromising security
- CIBA ping/push modes and long-polling enable real-time notifications and efficient token delivery
- client_secret_jwt authentication provides standardized JWT-based client authentication with enhanced security
- Protocol Buffer serialization reduces operational costs through 40-60% smaller cache footprint and faster processing
- SSRF protection defends against internal infrastructure probing and metadata exposure
- ECDSA support enables modern cryptography with smaller keys, faster operations, and compliance with latest security standards
- Result pattern simplifies codebase maintenance and reduces bugs from complex type hierarchies
What's Changed
Full Changelog: v1.6.0...v2.0
v1.6
🚀 Features
- Authentication Method References (AMR) support (RFC 8176)
AuthSessionauthentication methods tracking
✏️ Improvements
- Faster Base32 encode/decode
Detailed description
Authentication Method References (AMR) support
- Implements RFC 8176 to emit and interpret standardized AMR values (e.g.,
pwd,otp,mfa) in tokens and session state. Improves interoperability with OIDC-compliant clients and downstream policy engines.
AuthSession authentication methods tracking
- Stores the set of authentication methods used during sign-in, providing richer auditing, better risk evaluation, and smoother step-up authentication flows.
Faster Base32 encode/decode
- Optimized Base32 routines reduce CPU usage and memory allocations, improving throughput for TOTP operations commonly used in multi-factor authentication.
✅ Why it matters
- Ensures standards compliance per RFC 8176 for interoperability with OIDC systems
- Enables method-level tracking for better auditing and monitoring
- Improves performance and resource efficiency for MFA-related operations
What's changed
Full Changelog: v1.5...v1.6
v1.5
🚀 Features
- Multi-value claim support (PR#23)
- Added stub for CIBA
IUserDeviceAuthorizationHandlerinterface (PR#25)
🛠 Fixes
- Fixed routing-template resolution (PR#24)
✏️ Improvements
- Broader claim-type support
- Improved routing-template parsing and resolution
- Dependency updates to latest stable versions
Detailed description
Multi-value claim support
- JWTs that previously dropped all but the first value for repeated claim types (e.g., multiple roles) now correctly emit arrays. The Abblix.JWT package now aggregates claims of the same type into JSON arrays and parses them back accurately.
Added stub for CIBA IUserDeviceAuthorizationHandler interface
- Provides a placeholder
IUserDeviceAuthorizationHandlerimplementation that throws a detailed exception with guidance on implementing and registering a custom handler. This enables customers to integrate CIBA support incrementally while providing clear instructions for full implementation when they attempt to use the feature.
Fixed routing-template resolution
- The original token parser used a regex that stopped capturing fallback values at the first closing bracket, and its resolution loop could exit before all placeholders were replaced—resulting in literal
[route:…]fragments, malformed templates, and startup-time 404s. We broadened the regex to capture any character in the fallback and improved the loop to run until no further substitutions occur.
Broader claim-type support
- The Abblix.JWT now recognizes and converts a wider range of ClaimValueType into their proper JsonNode forms. This update brings full compliance with JWT standards and ensures downstream services receive the complete set of claims.
Improved routing-template parsing and resolution
- Enhanced regex implementation and iterative resolution algorithm ensuring complete placeholder substitution without premature termination.
✅ Why it matters
- Ensures complete representation of multi-value claims, preventing missing or truncated identity data
- Eliminates startup-time URL errors by making routing-template resolution reliable and debuggable
- Lays the foundation for seamless Client-Initiated Backchannel Authentication support with clear extension guidance
What's changed
Full Changelog: v1.4...v1.5
v1.4
🚀 Features
- Dynamic, configuration-driven route resolution in controller attributes (PR#22)
✏️ Improvements
- Centralized route configuration via
IConfiguration - Runtime endpoint discovery with
IEndpointResolver - Full compatibility with Swagger/OpenAPI
- Seamless support for Docker and Kubernetes environments
Detailed description
Dynamic, configuration-driven route resolution in controller attributes
- Tokenized route templates such as
[route:token?fallback]allow dynamic resolution of endpoint paths from configuration. - Supports environment- and tenant-specific routing without code modifications.
- Applies route templates via a reusable MVC convention and scans controller actions at startup.
- Parses route tokens using regular expressions and resolves them recursively from configuration.
- Applies resolved templates once at startup, ensuring zero runtime performance impact.
Centralized route configuration via IConfiguration
- Routes are defined in a centralized configuration section with support for nested token expansion and fallback values.
- Enables defining routes via configuration files, environment variables, or Kubernetes ConfigMaps.
- Supports route overrides per environment without rebuilding the application.
Runtime endpoint discovery with IEndpointResolver
- The
IEndpointResolverservice enables programmatic resolution of fully qualified URIs for controller actions. - Used within
DiscoveryControllerto generate consistent OpenID Connect metadata. - Relies on ASP.NET Core's routing system for accurate resolution.
Full compatibility with Swagger/OpenAPI
- Resolved routes integrate with ASP.NET Core’s routing and appear correctly in Swagger/OpenAPI documentation.
Seamless support for Docker and Kubernetes environments
- Supports runtime route configuration via environment variables or config maps.
- Routing logic is moved to configuration, reducing code complexity.
- Simplifies CI/CD workflows by decoupling routing from application logic.
✅ Why it matters
- Eliminates hardcoded paths in source code
- Enables routing updates without redeployments
- Supports multi-environment and multi-tenant configurations
- Improves maintainability in containerized environments
- Simplifies CI/CD workflows by decoupling routing from application logic
What's changed
Full Changelog: v1.3.1...v1.4
v1.3.1
🛠 Fixes
- Added validation for the
request_uriparameter in authorization requests to enhance security and compliance
Detailed description
Added validation for the request_uri parameter in authorization requests
- This update introduces validation for the
request_uriparameter in authorization requests, ensuring that only pre-registered or otherwise compliant URIs are processed. This enhancement prevents potential misuse or injection attacks and improves the server's compliance with OpenID Connect standards. Applications leveraging therequest_urifeature will benefit from increased security and reliability in their authorization workflows.
What's changed
Full Changelog: v1.3.0.1...v1.3.1
v1.3.0.1
🛠 Fixes
- Resolved issues with the Dependency Injection (DI) setup for classes managing Pushed Authorization Requests (PAR)
Detailed description
Resolved issues with the Dependency Injection (DI) setup for classes managing Pushed Authorization Requests (PAR)
- A fix was made to address issues with the Dependency Injection (DI) registration of classes involved in handling Pushed Authorization Requests (PAR). The problem was causing misconfigurations in service resolution, potentially leading to runtime errors in applications using the PAR feature. This update ensures that all necessary services are correctly registered and resolved within the DI container, improving overall stability and functionality.
What's changed
Full Changelog: v1.3.0...v1.3.0.1