From 6a0cacd509e99cde1167e635e6dd0fdf4a6a71ae Mon Sep 17 00:00:00 2001 From: Patrick Allwood Date: Tue, 20 Oct 2026 16:21:30 +0100 Subject: [PATCH] feat/rework-req-object-algs Makes the addition of request_object_signing_alg_values_supported a non-breaking change, to allow for a minor release. The default values will be updated during the next major release. --- docs/reference/options.rst | 8 +++++--- .../Options/EndpointOptions.cs | 12 +----------- .../Options/IdentityServerOptions.cs | 11 +++++++++++ .../Default/DiscoveryResponseGenerator.cs | 6 +++--- .../Validation/Default/JwtRequestValidator.cs | 6 +++--- .../Authorize/JwtRequestAuthorizeTests.cs | 2 +- .../Default/DiscoveryResponseGeneratorTests.cs | 17 +++++++---------- .../Default/JwtRequestValidatorTests.cs | 8 ++++---- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/reference/options.rst b/docs/reference/options.rst index ed1523ff..9dfb8e2e 100644 --- a/docs/reference/options.rst +++ b/docs/reference/options.rst @@ -24,6 +24,10 @@ IdentityServer Options * ``EnableAuthorizeResponseIssuerParam`` When enabled, the authorize response will include the issuer ``iss`` parameter, and advertises support in the discovery document. Defaults to ``false``. +* ``SupportedRequestObjectSigningAlgorithms`` + Specifies the signing algorithms that are permitted for JWT request objects. Defaults to empty, will be ``RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512`` in the next major version. + When set to a non-empty list, the specified algorithms will be accepted for JWT request objects and published in the discovery document. + Endpoints ^^^^^^^^^ Allows enabling/disabling individual endpoints, e.g. token, authorize, userinfo etc. @@ -32,9 +36,7 @@ By default all endpoints are enabled, but you can lock down your server by disab * ``EnableJwtRequestUri`` JWT request_uri processing is enabled on the authorize endpoint. Defaults to ``false``. -* ``SupportedJwtRequestSigningAlgorithms`` - Specifies the signing algorithms that are permitted for JWT request objects. Defaults to ``RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512``. - When set to a non-empty list, the specified algorithms will be accepted for JWT request objects and published in the discovery document. + * ``EnablePushedAuthorizationRequestEndpoint`` Enables the pushed authorization request endpoint. Defaults to ``true``. See :ref:`Pushed Authorization Requests `. diff --git a/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/EndpointOptions.cs b/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/EndpointOptions.cs index b49b99af..ef494121 100644 --- a/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/EndpointOptions.cs +++ b/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/EndpointOptions.cs @@ -1,10 +1,8 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Modified by Rock Solid Knowledge Ltd. Copyright in modifications 2026, Rock Solid Knowledge Ltd. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. -using System.Collections.Generic; -using System.Linq; - namespace Open.IdentityServer.Configuration; /// @@ -24,14 +22,6 @@ public class EndpointsOptions /// Gets or sets if JWT request_uri processing is enabled on the authorize endpoint. /// public bool EnableJwtRequestUri { get; set; } = false; - - /// - /// Gets or sets the supported JWT request signing algorithms. - /// Defaults to RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512. - /// A null or empty collection will omit the "request_object_signing_alg_values_supported" entry from the discovery document. - /// - public ICollection SupportedJwtRequestSigningAlgorithms { get; set; } = - IdentityServerConstants.SupportedSigningAlgorithms.ToHashSet(); /// /// Gets or sets a value indicating whether the token endpoint is enabled. diff --git a/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/IdentityServerOptions.cs b/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/IdentityServerOptions.cs index b1a3693f..603281e4 100644 --- a/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/IdentityServerOptions.cs +++ b/src/Open.IdentityServer/src/Configuration/DependencyInjection/Options/IdentityServerOptions.cs @@ -2,6 +2,9 @@ // Modified by Rock Solid Knowledge Ltd. Copyright in modifications 2026, Rock Solid Knowledge Ltd. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. +using System.Collections.Generic; +using System.Linq; + namespace Open.IdentityServer.Configuration; /// @@ -47,6 +50,14 @@ public class IdentityServerOptions /// public bool StrictJarValidation { get; set; } = false; + /// + /// Gets or sets the supported JWT request object signing algorithms. + /// Defaults to an empty collection. + /// From version 4.0.0, will default to RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512. + /// A null or empty collection will omit the "request_object_signing_alg_values_supported" entry from the discovery document. + /// + public ICollection SupportedRequestObjectSigningAlgorithms { get; set; } = []; + /// /// Gets or sets the endpoint configuration. /// diff --git a/src/Open.IdentityServer/src/ResponseHandling/Default/DiscoveryResponseGenerator.cs b/src/Open.IdentityServer/src/ResponseHandling/Default/DiscoveryResponseGenerator.cs index d6ac3680..24e877a3 100644 --- a/src/Open.IdentityServer/src/ResponseHandling/Default/DiscoveryResponseGenerator.cs +++ b/src/Open.IdentityServer/src/ResponseHandling/Default/DiscoveryResponseGenerator.cs @@ -337,12 +337,12 @@ where scope.ShowInDiscoveryDocument entries.Add(OidcConstants.Discovery.RequestParameterSupported, true); entries.Add(OidcConstants.Discovery.AuthorizationResponseIssParameterSupported, Options.EnableAuthorizeResponseIssuerParam); - if (Options.Endpoints.SupportedJwtRequestSigningAlgorithms != null && - Options.Endpoints.SupportedJwtRequestSigningAlgorithms.Count != 0) + if (Options.SupportedRequestObjectSigningAlgorithms != null && + Options.SupportedRequestObjectSigningAlgorithms.Count != 0) { entries.Add( OidcConstants.Discovery.RequestObjectSigningAlgorithmsSupported, - Options.Endpoints.SupportedJwtRequestSigningAlgorithms); + Options.SupportedRequestObjectSigningAlgorithms); } if (Options.Endpoints.EnableJwtRequestUri) diff --git a/src/Open.IdentityServer/src/Validation/Default/JwtRequestValidator.cs b/src/Open.IdentityServer/src/Validation/Default/JwtRequestValidator.cs index 99206442..b8f9382f 100644 --- a/src/Open.IdentityServer/src/Validation/Default/JwtRequestValidator.cs +++ b/src/Open.IdentityServer/src/Validation/Default/JwtRequestValidator.cs @@ -198,10 +198,10 @@ protected virtual async Task ValidateJwtAsync(string jwtTokenStrin RequireSignedTokens = true, RequireExpirationTime = true }; - - if (Options.Endpoints.SupportedJwtRequestSigningAlgorithms?.Any() == true) + + if (Options.SupportedRequestObjectSigningAlgorithms?.Count > 0) { - tokenValidationParameters.ValidAlgorithms = Options.Endpoints.SupportedJwtRequestSigningAlgorithms; + tokenValidationParameters.ValidAlgorithms = Options.SupportedRequestObjectSigningAlgorithms; } if (Options.StrictJarValidation) diff --git a/src/Open.IdentityServer/test/Open.IdentityServer.IntegrationTests/Endpoints/Authorize/JwtRequestAuthorizeTests.cs b/src/Open.IdentityServer/test/Open.IdentityServer.IntegrationTests/Endpoints/Authorize/JwtRequestAuthorizeTests.cs index f14f62a2..e9735d5c 100644 --- a/src/Open.IdentityServer/test/Open.IdentityServer.IntegrationTests/Endpoints/Authorize/JwtRequestAuthorizeTests.cs +++ b/src/Open.IdentityServer/test/Open.IdentityServer.IntegrationTests/Endpoints/Authorize/JwtRequestAuthorizeTests.cs @@ -271,7 +271,7 @@ public async Task authorize_should_accept_valid_JWT_request_object_parameters_us public async Task authorize_should_accept_valid_JWT_request_object_parameters_using_symmetric_jwk() { // Defaults do not include HS algs - _mockPipeline.Options.Endpoints.SupportedJwtRequestSigningAlgorithms.Add("HS256"); + _mockPipeline.Options.SupportedRequestObjectSigningAlgorithms.Add("HS256"); var requestJwt = CreateRequestJwt( issuer: _client.ClientId, diff --git a/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/ResponseHandling/Default/DiscoveryResponseGeneratorTests.cs b/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/ResponseHandling/Default/DiscoveryResponseGeneratorTests.cs index cae69d08..0e996e0b 100644 --- a/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/ResponseHandling/Default/DiscoveryResponseGeneratorTests.cs +++ b/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/ResponseHandling/Default/DiscoveryResponseGeneratorTests.cs @@ -480,7 +480,7 @@ public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointDisabled_Sho public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointDisabled_ShouldNotContainRequestParameterSigningAlgValuesSupported() { _options.Endpoints.EnableAuthorizeEndpoint = false; - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = ["RS256", "ES256"]; + _options.SupportedRequestObjectSigningAlgorithms = ["RS256", "ES256"]; var sut = CreateSut(); @@ -493,7 +493,7 @@ public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointDisabled_Sho public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndNullSupportedJwtRequestSigningAlgorithms_ShouldNotContainRequestObjectSigningAlgorithmsSupported() { _options.Endpoints.EnableAuthorizeEndpoint = true; - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = null; + _options.SupportedRequestObjectSigningAlgorithms = null; var sut = CreateSut(); @@ -506,7 +506,7 @@ public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndNu public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndNoSupportedJwtRequestSigningAlgorithms_ShouldNotContainRequestObjectSigningAlgorithmsSupported() { _options.Endpoints.EnableAuthorizeEndpoint = true; - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = []; + _options.SupportedRequestObjectSigningAlgorithms = []; var sut = CreateSut(); @@ -516,10 +516,10 @@ public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndNo } [Fact] - public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndJwtSigningAlgorithmsSet_ShouldShouldContainSetSigningAlgorithms() + public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndRequestObjectSigningAlgorithmsSet_ShouldShouldContainSetSigningAlgorithms() { _options.Endpoints.EnableAuthorizeEndpoint = true; - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = ["RS256", "ES256"]; + _options.SupportedRequestObjectSigningAlgorithms = ["RS256", "ES256"]; var sut = CreateSut(); @@ -532,7 +532,7 @@ public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndJw } [Fact] - public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndJwtSigningAlgorithmsDefault_ShouldShouldContainDefaultSigningAlgorithms() + public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndRequestObjectSigningAlgorithmsDefault_ShouldShouldOmitSigningAlgorithms() { _options.Endpoints.EnableAuthorizeEndpoint = true; @@ -540,10 +540,7 @@ public async Task CreateDiscoveryDocumentAsync_WhenAuthorizeEndpointEnabledAndJw var actual = await sut.CreateDiscoveryDocumentAsync("https://open.ids.url/", "https://open.ids.url"); - actual.Should().ContainKey(OidcConstants.Discovery.RequestObjectSigningAlgorithmsSupported) - .WhoseValue.Should().BeEquivalentTo(new[] { "RS256", "RS384", "RS512", - "PS256", "PS384", "PS512", - "ES256", "ES384", "ES512" }); + actual.Should().NotContainKey(OidcConstants.Discovery.RequestObjectSigningAlgorithmsSupported); } [Fact] diff --git a/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/Validation/Default/JwtRequestValidatorTests.cs b/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/Validation/Default/JwtRequestValidatorTests.cs index 54e86f69..763ce644 100644 --- a/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/Validation/Default/JwtRequestValidatorTests.cs +++ b/src/Open.IdentityServer/test/Open.IdentityServer.UnitTests/Validation/Default/JwtRequestValidatorTests.cs @@ -80,7 +80,7 @@ public async Task ValidateAsync_WhenCalled_ShouldCreateTelemetryTrace() [MemberData(nameof(SigningAlgorithms))] public async Task ValidateAsync_WhenSigningAlgorithmIsSupported_ShouldSucceed(string algorithm) { - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = + _options.SupportedRequestObjectSigningAlgorithms = [ GetAlternativeAlgorithm(algorithm), algorithm @@ -97,7 +97,7 @@ public async Task ValidateAsync_WhenSigningAlgorithmIsSupported_ShouldSucceed(st [MemberData(nameof(SigningAlgorithms))] public async Task ValidateAsync_WhenSigningAlgorithmIsNotSupported_ShouldFail(string algorithm) { - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = [GetAlternativeAlgorithm(algorithm)]; + _options.SupportedRequestObjectSigningAlgorithms = [GetAlternativeAlgorithm(algorithm)]; var (client, jwt) = CreateSignedJwt(algorithm); @@ -110,7 +110,7 @@ public async Task ValidateAsync_WhenSigningAlgorithmIsNotSupported_ShouldFail(st [MemberData(nameof(SigningAlgorithms))] public async Task ValidateAsync_WhenSupportedSigningAlgorithmsIsNull_ShouldSucceed(string algorithm) { - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = null; + _options.SupportedRequestObjectSigningAlgorithms = null; var (client, jwt) = CreateSignedJwt(algorithm); @@ -123,7 +123,7 @@ public async Task ValidateAsync_WhenSupportedSigningAlgorithmsIsNull_ShouldSucce [MemberData(nameof(SigningAlgorithms))] public async Task ValidateAsync_WhenSupportedSigningAlgorithmsIsEmpty_ShouldSucceed(string algorithm) { - _options.Endpoints.SupportedJwtRequestSigningAlgorithms = []; + _options.SupportedRequestObjectSigningAlgorithms = []; var (client, jwt) = CreateSignedJwt(algorithm);