Support OpenIddict 7.0 client-assertion audience via discovery - #42
Merged
Conversation
Rebased onto current main (which made GetClientAccessToken take the token endpoint explicitly and fixed the multi-scope request). The eryph server upgraded to OpenIddict 7.0 requires the issuer as the client-assertion audience and the client-authentication+jwt token type; older servers expect the token endpoint audience. ClientCredentials now reads the discovery document from the identity provider and detects the custom metadata flag eryph_client_assertion_audience to choose the format, then passes the resolved audience/token type to the GetClientAccessToken primitive (which gains optional audience/tokenType parameters and stays a single request). Every eryph server serves the discovery document, so a failure to read it surfaces as an AccessTokenException rather than silently downgrading to a format the server would reject.
fw2568
force-pushed
the
feature/openiddict7-client-assertion
branch
from
May 29, 2026 14:20
340afa1 to
9c7050b
Compare
Fetch the discovery document before pinning the private key in unmanaged memory, and unpin it immediately after reading the RSA parameters, so the plaintext key is exposed for as short a time as possible (no longer held across the discovery call).
There was a problem hiding this comment.
Pull request overview
This PR updates client-credential token acquisition to support eryph identity servers using OpenIddict 7.0 discovery metadata while preserving legacy token assertion behavior.
Changes:
- Adds discovery-document parsing to choose client-assertion audience and JWT
typ. - Extends token request generation to accept custom audience/token type.
- Adds tests for new-server, legacy-server, and discovery-failure paths.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/Eryph.IdentityModel.Clients/ClientCredentials.cs |
Resolves assertion format from discovery metadata before requesting tokens. |
src/Eryph.IdentityModel.Clients/Eryph.IdentityModel.Clients.csproj |
Adds OpenID Connect protocol metadata parsing dependency. |
src/Eryph.IdentityModel/Clients/HttpClientRequestExtensions.cs |
Allows token requests to override assertion audience and JWT header type. |
test/Eryph.IdentityModel.Clients.Tests/ClientCredentialsTests.cs |
Adds coverage for discovery-driven assertion behavior. |
test/Eryph.IdentityModel.Tests/HttpClientExtensionsTests.cs |
Adds direct assertion-generation tests for audience and token type. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ibility Adding the audience/tokenType parameters as optionals changed the public method's CLR signature, which would break callers compiled against the previous package version (MissingMethodException) when only the package is upgraded. Keep the original 5-parameter overload and have it delegate to the new 7-parameter overload.
Comment on lines
+125
to
+132
| var usesIssuerAudience = | ||
| configuration.AdditionalData.TryGetValue(ClientAssertionAudienceMetadata, out var value) | ||
| && string.Equals(value?.ToString(), ClientAssertionAudienceIssuer, StringComparison.OrdinalIgnoreCase) | ||
| && !string.IsNullOrEmpty(configuration.Issuer); | ||
|
|
||
| return usesIssuerAudience | ||
| ? (configuration.Issuer, ClientAuthenticationJwtType) | ||
| : (_tokenUrl.AbsoluteUri, null); |
If the discovery document advertises eryph_client_assertion_audience=issuer but contains no issuer, the metadata is invalid: throw instead of downgrading to a legacy token-endpoint assertion the server would reject. Add a test.
fw2568
added a commit
to eryph-org/dotnet-clientruntime
that referenced
this pull request
May 30, 2026
…Clients Bump Eryph.IdentityModel.Clients to the preview build that negotiates the client-assertion audience via discovery (eryph-org/dotnet-identitymodel#42), so the new auth flows through ClientRuntime for end-to-end testing against an OpenIddict 7 eryph server. Pinned to the PR preview on the dbosoft feed; to be re-pinned to the released version once dotnet-identitymodel#42 merges.
fw2568
added a commit
to eryph-org/dotnet-clientruntime
that referenced
this pull request
May 31, 2026
…ients) (#66) * Consume OpenIddict 7 client-assertion preview of Eryph.IdentityModel.Clients Bump Eryph.IdentityModel.Clients to the preview build that negotiates the client-assertion audience via discovery (eryph-org/dotnet-identitymodel#42), so the new auth flows through ClientRuntime for end-to-end testing against an OpenIddict 7 eryph server. Pinned to the PR preview on the dbosoft feed; to be re-pinned to the released version once dotnet-identitymodel#42 merges. * Use released Eryph.IdentityModel.Clients 0.7.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The eryph identity server is moving to OpenIddict 7.0, which requires the issuer as the client-assertion audience and the new
client-authentication+jwttoken type (the oldtoken_endpointaudience is rejected). To keep a single client library working against both old and new eryph servers, the assertion format is now negotiated from the server's discovery document.ClientCredentialsreads the OpenID Connect discovery document from the identity provider and detects the custom metadata flageryph_client_assertion_audience: when present (issuer) it uses the issuer as the audience and theclient-authentication+jwttype; otherwise it falls back to the token-endpoint audience (older servers). Every eryph server serves discovery, so a failure to read it surfaces as anAccessTokenExceptionrather than silently downgrading to a format the server would reject.GetClientAccessTokenstays a single-request primitive and gains optionalaudience/tokenTypeparameters so the caller can pass the negotiated values.Microsoft.IdentityModel.Protocols.OpenIdConnect8.2.0, matching the IdentityModel version already used in the repo (the wholeMicrosoft.IdentityModel.*/System.IdentityModel.Tokens.Jwtstack resolves uniformly to 8.2.0, with no advisory warnings).GetClientAccessTokenprimitive and theClientCredentialsend-to-end path).The private key is also pinned in unmanaged memory only briefly (around reading the RSA parameters), not across the discovery call.