mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Merge pull request #2205 from DuendeSoftware/beh/additional-metadata-fields
Additional Discovery Document Fields
This commit is contained in:
commit
dd3932febd
15 changed files with 823 additions and 43 deletions
|
|
@ -62,11 +62,26 @@ public class DiscoveryOptions
|
|||
/// </summary>
|
||||
public bool ShowTokenEndpointAuthenticationMethods { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Show revocation endpoint authentication methods
|
||||
/// </summary>
|
||||
public bool ShowRevocationEndpointAuthenticationMethods { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Show introspection endpoint authentication methods
|
||||
/// </summary>
|
||||
public bool ShowIntrospectionEndpointAuthenticationMethods { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Turns relative paths that start with ~/ into absolute paths
|
||||
/// </summary>
|
||||
public bool ExpandRelativePathsInCustomEntries { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Options for how the dynamic client registration endpoint is shown in the discovery document
|
||||
/// </summary>
|
||||
public DynamicClientRegistrationDiscoveryOptions DynamicClientRegistration { get; set; } = new DynamicClientRegistrationDiscoveryOptions();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the maxage value of the cache control header (in seconds) of the HTTP response. This gives clients a hint how often they should refresh their cached copy of the discovery document. If set to 0 no-cache headers will be set. Defaults to null, which does not set the header.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
#nullable enable
|
||||
namespace Duende.IdentityServer.Configuration;
|
||||
|
||||
public enum RegistrationEndpointMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Will not show a registration endpoint in the discovery document
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Will use the static URL from <see cref="DynamicClientRegistrationDiscoveryOptions.StaticRegistrationEndpoint"/>
|
||||
/// </summary>
|
||||
Static,
|
||||
|
||||
/// <summary>
|
||||
/// Will infer the URL dynamically based on the host
|
||||
/// </summary>
|
||||
Inferred
|
||||
}
|
||||
|
||||
public class DynamicClientRegistrationDiscoveryOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the registration endpoint
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the registration endpoint.
|
||||
/// </value>
|
||||
public RegistrationEndpointMode RegistrationEndpointMode { get; set; } = RegistrationEndpointMode.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the custom registration endpoint
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The URL of the authorization endpoint to use in the discovery document if <see cref="RegistrationEndpointMode"/> is set to <see cref="RegistrationEndpointMode.Static"/>.
|
||||
/// </value>
|
||||
public Uri? StaticRegistrationEndpoint { get; set; }
|
||||
}
|
||||
|
|
@ -215,6 +215,12 @@ public static class IdentityServerApplicationBuilderExtensions
|
|||
{
|
||||
throw new InvalidOperationException("CorsPolicyName is not configured");
|
||||
}
|
||||
|
||||
if (options.Discovery.DynamicClientRegistration.RegistrationEndpointMode == RegistrationEndpointMode.Static
|
||||
&& options.Discovery.DynamicClientRegistration.StaticRegistrationEndpoint == null)
|
||||
{
|
||||
throw new InvalidOperationException("DynamicClientRegistration.CustomRegistrationEndpoint must be set when using static registration endpoint type.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static object? TestService(IServiceProvider serviceProvider, Type service, ILogger logger, string? message = null, bool doThrow = true)
|
||||
|
|
|
|||
|
|
@ -257,6 +257,7 @@ public static class IdentityServerConstants
|
|||
public const string DeviceAuthorization = ConnectPathPrefix + "/deviceauthorization";
|
||||
public const string PushedAuthorization = ConnectPathPrefix + "/par";
|
||||
public const string OAuthMetadata = ".well-known/oauth-authorization-server";
|
||||
public const string DynamicClientRegistration = ConnectPathPrefix + "/dcr";
|
||||
|
||||
|
||||
public const string MtlsPathPrefix = ConnectPathPrefix + "/mtls";
|
||||
|
|
|
|||
|
|
@ -322,23 +322,24 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator
|
|||
entries.Add(OidcConstants.Discovery.ResponseModesSupported, Constants.SupportedResponseModes.ToArray());
|
||||
}
|
||||
|
||||
var supportedAuthMethods = GetSupportedAuthMethods();
|
||||
// misc
|
||||
if (Options.Discovery.ShowTokenEndpointAuthenticationMethods)
|
||||
{
|
||||
var types = SecretParsers.GetAvailableAuthenticationMethods().ToList();
|
||||
if (Options.MutualTls.Enabled)
|
||||
{
|
||||
types.Add(OidcConstants.EndpointAuthenticationMethods.TlsClientAuth);
|
||||
types.Add(OidcConstants.EndpointAuthenticationMethods.SelfSignedTlsClientAuth);
|
||||
}
|
||||
entries.Add(OidcConstants.Discovery.TokenEndpointAuthenticationMethodsSupported, types);
|
||||
entries.Add(OidcConstants.Discovery.TokenEndpointAuthenticationMethodsSupported, supportedAuthMethods);
|
||||
AddSigningAlgorithmsForEndpointIfNeeded(OidcConstants.Discovery.TokenEndpointAuthSigningAlgorithmsSupported, entries, supportedAuthMethods);
|
||||
}
|
||||
|
||||
if (types.Contains(OidcConstants.EndpointAuthenticationMethods.PrivateKeyJwt) &&
|
||||
!IEnumerableExtensions.IsNullOrEmpty(Options.SupportedClientAssertionSigningAlgorithms))
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.TokenEndpointAuthSigningAlgorithmsSupported,
|
||||
Options.SupportedClientAssertionSigningAlgorithms);
|
||||
}
|
||||
if (Options.Discovery.ShowRevocationEndpointAuthenticationMethods)
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.RevocationEndpointAuthenticationMethodsSupported, supportedAuthMethods);
|
||||
AddSigningAlgorithmsForEndpointIfNeeded(OidcConstants.Discovery.RevocationEndpointAuthSigningAlgorithmsSupported, entries, supportedAuthMethods);
|
||||
}
|
||||
|
||||
if (Options.Discovery.ShowIntrospectionEndpointAuthenticationMethods)
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.IntrospectionEndpointAuthenticationMethodsSupported, supportedAuthMethods);
|
||||
AddSigningAlgorithmsForEndpointIfNeeded(OidcConstants.Discovery.IntrospectionEndpointAuthSigningAlgorithmsSupported, entries, supportedAuthMethods);
|
||||
}
|
||||
|
||||
var signingCredentials = await Keys.GetAllSigningCredentialsAsync();
|
||||
|
|
@ -346,6 +347,16 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator
|
|||
{
|
||||
var signingAlgorithms = signingCredentials.Select(c => c.Algorithm).Distinct();
|
||||
entries.Add(OidcConstants.Discovery.IdTokenSigningAlgorithmsSupported, signingAlgorithms);
|
||||
|
||||
if (Options.Endpoints.EnableUserInfoEndpoint)
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.UserInfoSigningAlgorithmsSupported, signingAlgorithms);
|
||||
}
|
||||
|
||||
if (Options.Endpoints.EnableIntrospectionEndpoint)
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.IntrospectionSigningAlgorithmsSupported, signingAlgorithms);
|
||||
}
|
||||
}
|
||||
|
||||
entries.Add(OidcConstants.Discovery.SubjectTypesSupported, SubjectTypesSupported);
|
||||
|
|
@ -384,6 +395,12 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator
|
|||
entries.Add(OidcConstants.Discovery.BackchannelTokenDeliveryModesSupported,
|
||||
new[] { OidcConstants.BackchannelTokenDeliveryModes.Poll });
|
||||
entries.Add(OidcConstants.Discovery.BackchannelUserCodeParameterSupported, true);
|
||||
|
||||
if (!IEnumerableExtensions.IsNullOrEmpty(Options.SupportedRequestObjectSigningAlgorithms))
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.BackchannelAuthenticationRequestSigningAlgValuesSupported,
|
||||
Options.SupportedRequestObjectSigningAlgorithms);
|
||||
}
|
||||
}
|
||||
|
||||
if (Options.Endpoints.EnableTokenEndpoint &&
|
||||
|
|
@ -392,6 +409,22 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator
|
|||
entries.Add(OidcConstants.Discovery.DPoPSigningAlgorithmsSupported, Options.DPoP.SupportedDPoPSigningAlgorithms);
|
||||
}
|
||||
|
||||
switch (Options.Discovery.DynamicClientRegistration.RegistrationEndpointMode)
|
||||
{
|
||||
case RegistrationEndpointMode.Static:
|
||||
if (Options.Discovery.DynamicClientRegistration.StaticRegistrationEndpoint != null)
|
||||
{
|
||||
entries.Add(OidcConstants.Discovery.RegistrationEndpoint, Options.Discovery.DynamicClientRegistration.StaticRegistrationEndpoint.ToString());
|
||||
}
|
||||
break;
|
||||
case RegistrationEndpointMode.Inferred:
|
||||
entries.Add(OidcConstants.Discovery.RegistrationEndpoint, baseUrl + ProtocolRoutePaths.DynamicClientRegistration);
|
||||
break;
|
||||
case RegistrationEndpointMode.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// custom entries
|
||||
if (!IEnumerableExtensions.IsNullOrEmpty(Options.Discovery.CustomEntries))
|
||||
{
|
||||
|
|
@ -541,4 +574,24 @@ public class DiscoveryResponseGenerator : IDiscoveryResponseGenerator
|
|||
|
||||
return webKeys;
|
||||
}
|
||||
|
||||
private List<string> GetSupportedAuthMethods()
|
||||
{
|
||||
var types = SecretParsers.GetAvailableAuthenticationMethods().ToList();
|
||||
if (Options.MutualTls.Enabled)
|
||||
{
|
||||
types.Add(OidcConstants.EndpointAuthenticationMethods.TlsClientAuth);
|
||||
types.Add(OidcConstants.EndpointAuthenticationMethods.SelfSignedTlsClientAuth);
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
private void AddSigningAlgorithmsForEndpointIfNeeded(string key, Dictionary<string, object> entries, IEnumerable<string> supportedAuthMethods)
|
||||
{
|
||||
if (supportedAuthMethods.Contains(OidcConstants.EndpointAuthenticationMethods.PrivateKeyJwt) && !IEnumerableExtensions.IsNullOrEmpty(Options.SupportedClientAssertionSigningAlgorithms))
|
||||
{
|
||||
entries.Add(key, Options.SupportedClientAssertionSigningAlgorithms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.Configuration;
|
||||
using Duende.IdentityServer.Endpoints.Results;
|
||||
|
|
@ -77,8 +78,99 @@ public class DiscoveryEndpointTests
|
|||
algorithmsSupported.ShouldContain(SecurityAlgorithms.EcdsaSha256);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task UserInfo_signing_algorithms_supported_should_match_signing_key()
|
||||
{
|
||||
var key = CryptoHelper.CreateECDsaSecurityKey(JsonWebKeyECTypes.P256);
|
||||
var expectedAlgorithm = SecurityAlgorithms.EcdsaSha256;
|
||||
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += services =>
|
||||
{
|
||||
// add key to standard RSA key
|
||||
services.AddIdentityServerBuilder()
|
||||
.AddSigningCredential(key, expectedAlgorithm);
|
||||
};
|
||||
pipeline.Initialize();
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
var algorithmsSupported = result.UserInfoSigningAlgorithmsSupported;
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(2);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.RsaSha256);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.EcdsaSha256);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task UserInfo_signing_algorithms_supported_should_not_be_present_if_userinfo_endpoint_disabled()
|
||||
{
|
||||
var key = CryptoHelper.CreateECDsaSecurityKey(JsonWebKeyECTypes.P256);
|
||||
var expectedAlgorithm = SecurityAlgorithms.EcdsaSha256;
|
||||
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += services =>
|
||||
{
|
||||
// add key to standard RSA key
|
||||
services.AddIdentityServerBuilder()
|
||||
.AddSigningCredential(key, expectedAlgorithm);
|
||||
};
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.Endpoints.EnableUserInfoEndpoint = false;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
result.UserInfoSigningAlgorithmsSupported.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task Introspection_signing_algorithms_supported_should_match_signing_key()
|
||||
{
|
||||
var key = CryptoHelper.CreateECDsaSecurityKey(JsonWebKeyECTypes.P256);
|
||||
var expectedAlgorithm = SecurityAlgorithms.EcdsaSha256;
|
||||
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += services =>
|
||||
{
|
||||
// add key to standard RSA key
|
||||
services.AddIdentityServerBuilder()
|
||||
.AddSigningCredential(key, expectedAlgorithm);
|
||||
};
|
||||
pipeline.Initialize();
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
var algorithmsSupported = result.IntrospectionSigningAlgorithmsSupported;
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(2);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.RsaSha256);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.EcdsaSha256);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task Introspection_signing_algorithms_supported_should_not_be_present_if_introspection_endpoint_disabled()
|
||||
{
|
||||
var key = CryptoHelper.CreateECDsaSecurityKey(JsonWebKeyECTypes.P256);
|
||||
var expectedAlgorithm = SecurityAlgorithms.EcdsaSha256;
|
||||
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += services =>
|
||||
{
|
||||
// add key to standard RSA key
|
||||
services.AddIdentityServerBuilder()
|
||||
.AddSigningCredential(key, expectedAlgorithm);
|
||||
};
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.Endpoints.EnableIntrospectionEndpoint = false;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
result.IntrospectionSigningAlgorithmsSupported.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
|
|
@ -216,7 +308,6 @@ public class DiscoveryEndpointTests
|
|||
result.Issuer.ShouldBe("https://грант.рф");
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task prompt_values_supported_should_contain_defaults()
|
||||
|
|
@ -376,6 +467,51 @@ public class DiscoveryEndpointTests
|
|||
var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
result.MtlsEndpointAliases.PushedAuthorizationRequestEndpoint.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task registration_endpoint_should_be_custom_when_static_type_and_custom_endpoint_set()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.Discovery.DynamicClientRegistration.RegistrationEndpointMode = RegistrationEndpointMode.Static;
|
||||
pipeline.Options.Discovery.DynamicClientRegistration.StaticRegistrationEndpoint = new Uri("https://custom.example.com/register");
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data.ShouldContainKey(OidcConstants.Discovery.RegistrationEndpoint);
|
||||
data[OidcConstants.Discovery.RegistrationEndpoint].GetString().ShouldBe("https://custom.example.com/register");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task registration_endpoint_should_be_default_when_dynamic_type()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.Discovery.DynamicClientRegistration.RegistrationEndpointMode = RegistrationEndpointMode.Inferred;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data.ShouldContainKey(OidcConstants.Discovery.RegistrationEndpoint);
|
||||
data[OidcConstants.Discovery.RegistrationEndpoint].GetString().ShouldBe("https://server/connect/dcr");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task registration_endpoint_should_not_be_present_when_none_type()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.Discovery.DynamicClientRegistration.RegistrationEndpointMode = RegistrationEndpointMode.None;
|
||||
|
||||
var result = await pipeline.BackChannelClient.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
data.ShouldNotContainKey(OidcConstants.Discovery.RegistrationEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
class DiscoCustomizaztion : IHttpResponseWriter<DiscoveryDocumentResult>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public abstract class DiscoveryEndpointTestsBase
|
||||
{
|
||||
protected static IdentityServerPipeline CreatePipelineWithJwtBearer()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += svcs =>
|
||||
svcs.AddIdentityServerBuilder().AddJwtBearerClientAuthentication();
|
||||
pipeline.Initialize();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> NullOrEmptySupportedAlgorithms() =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[] { Enumerable.Empty<string>() },
|
||||
new object[] { null }
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpointTests_introspection_endpoint_auth_methods_supported : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - introspection_endpoint_auth_methods_supported";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_methods_supported_should_default_to_basic_auth_and_post_body()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = false;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.IntrospectionEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(2);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_methods_supported_should_include_tls_client_and_self_signed_tls_client_when_mtls_is_enabled()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = true;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.IntrospectionEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(4);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.TlsClientAuth);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.SelfSignedTlsClientAuth);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_methods_supported_should_include_private_key_jwt_when_jwt_bearer_is_enabled()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = false;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.IntrospectionEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(3);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PrivateKeyJwt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpointTests_introspection_endpoint_auth_signing_algs_supported : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - introspection_endpoint_auth_signing_alg_values_supported";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_signing_alg_values_supported_should_match_configuration()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms =
|
||||
[
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
SecurityAlgorithms.EcdsaSha256
|
||||
];
|
||||
pipeline.Options.Discovery.ShowIntrospectionEndpointAuthenticationMethods = true;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var algorithmsSupported = disco.IntrospectionEndpointAuthenticationSigningAlgorithmsSupported;
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(2);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.RsaSsaPssSha256);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.EcdsaSha256);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_signing_alg_values_supported_should_default_to_rs_ps_es()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.Discovery.ShowIntrospectionEndpointAuthenticationMethods = true;
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
var algorithmsSupported = result.IntrospectionEndpointAuthenticationSigningAlgorithmsSupported;
|
||||
|
||||
algorithmsSupported.ShouldBe([
|
||||
SecurityAlgorithms.RsaSha256,
|
||||
SecurityAlgorithms.RsaSha384,
|
||||
SecurityAlgorithms.RsaSha512,
|
||||
SecurityAlgorithms.RsaSsaPssSha384,
|
||||
SecurityAlgorithms.RsaSsaPssSha512,
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
SecurityAlgorithms.EcdsaSha256,
|
||||
SecurityAlgorithms.EcdsaSha384,
|
||||
SecurityAlgorithms.EcdsaSha512,
|
||||
], ignoreOrder: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_signing_alg_values_supported_should_not_be_present_if_private_key_jwt_is_not_configured()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = [SecurityAlgorithms.RsaSha256];
|
||||
pipeline.Options.Discovery.ShowIntrospectionEndpointAuthenticationMethods = true;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
// Verify assumptions
|
||||
disco.IsError.ShouldBeFalse();
|
||||
disco.IntrospectionEndpointAuthenticationMethodsSupported.ShouldNotContain("private_key_jwt");
|
||||
disco.IntrospectionEndpointAuthenticationMethodsSupported.ShouldNotContain("client_secret_jwt");
|
||||
|
||||
// Assert that we got no signing algs.
|
||||
disco.IntrospectionEndpointAuthenticationSigningAlgorithmsSupported.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(NullOrEmptySupportedAlgorithms))]
|
||||
[Trait("Category", Category)]
|
||||
public async Task introspection_endpoint_auth_signing_alg_values_supported_should_not_be_present_if_option_is_null_or_empty(
|
||||
ICollection<string> algorithms)
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = algorithms;
|
||||
pipeline.Options.Discovery.ShowIntrospectionEndpointAuthenticationMethods = true;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey(OidcConstants.Discovery.IntrospectionEndpointAuthSigningAlgorithmsSupported);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpointTests_revocation_endpoint_auth_methods_supported : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - revocation_endpoint_auth_methods_supported";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_methods_supported_should_default_to_basic_auth_and_post_body()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = false;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.RevocationEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(2);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_methods_supported_should_include_tls_client_and_self_signed_tls_client_when_mtls_is_enabled()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = true;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.RevocationEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(4);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.TlsClientAuth);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.SelfSignedTlsClientAuth);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_methods_supported_should_include_private_key_jwt_when_jwt_bearer_is_enabled()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = false;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.RevocationEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(3);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PrivateKeyJwt);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpointTests_revocation_endpoint_auth_signing_algs_supported : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - revocation_endpoint_auth_signing_alg_values_supported";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_signing_alg_values_supported_should_match_configuration()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms =
|
||||
[
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
SecurityAlgorithms.EcdsaSha256
|
||||
];
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var algorithmsSupported = disco.RevocationEndpointAuthenticationSigningAlgorithmsSupported;
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(2);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.RsaSsaPssSha256);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.EcdsaSha256);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_signing_alg_values_supported_should_default_to_rs_ps_es()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
|
||||
result.IsError.ShouldBeFalse();
|
||||
var algorithmsSupported = result.RevocationEndpointAuthenticationSigningAlgorithmsSupported;
|
||||
|
||||
algorithmsSupported.ShouldBe([
|
||||
SecurityAlgorithms.RsaSha256,
|
||||
SecurityAlgorithms.RsaSha384,
|
||||
SecurityAlgorithms.RsaSha512,
|
||||
SecurityAlgorithms.RsaSsaPssSha384,
|
||||
SecurityAlgorithms.RsaSsaPssSha512,
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
SecurityAlgorithms.EcdsaSha256,
|
||||
SecurityAlgorithms.EcdsaSha384,
|
||||
SecurityAlgorithms.EcdsaSha512,
|
||||
], ignoreOrder: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_signing_alg_values_supported_should_not_be_present_if_private_key_jwt_is_not_configured()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = [SecurityAlgorithms.RsaSha256];
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
disco.IsError.ShouldBeFalse();
|
||||
disco.RevocationEndpointAuthenticationMethodsSupported.ShouldNotContain("private_key_jwt");
|
||||
disco.RevocationEndpointAuthenticationMethodsSupported.ShouldNotContain("client_secret_jwt");
|
||||
disco.RevocationEndpointAuthenticationSigningAlgorithmsSupported.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(NullOrEmptySupportedAlgorithms))]
|
||||
[Trait("Category", Category)]
|
||||
public async Task revocation_endpoint_auth_signing_alg_values_supported_should_not_be_present_if_option_is_null_or_empty(
|
||||
ICollection<string> algorithms)
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = algorithms;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey(OidcConstants.Discovery.RevocationEndpointAuthSigningAlgorithmsSupported);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpointTests_token_endpoint_auth_methods_supported : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - token_endpoint_auth_methods_supported";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task token_endpoint_auth_methods_supported_should_default_to_basic_auth_and_post_body()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = false;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.TokenEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(2);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task token_endpoint_auth_methods_supported_should_include_tls_client_and_self_signed_tls_client_when_mtls_is_enabled()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = true;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.TokenEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(4);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.TlsClientAuth);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.SelfSignedTlsClientAuth);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task token_endpoint_auth_methods_supported_should_include_private_key_jwt_when_jwt_bearer_is_enabled()
|
||||
{
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.MutualTls.Enabled = false;
|
||||
|
||||
var disco = await pipeline.BackChannelClient
|
||||
.GetDiscoveryDocumentAsync("https://server/.well-known/openid-configuration");
|
||||
disco.IsError.ShouldBeFalse();
|
||||
|
||||
var authMethodsSupported = disco.TokenEndpointAuthenticationMethodsSupported;
|
||||
|
||||
authMethodsSupported.Count().ShouldBe(3);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.BasicAuthentication);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PostBody);
|
||||
authMethodsSupported.ShouldContain(OidcConstants.EndpointAuthenticationMethods.PrivateKeyJwt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5,12 +5,11 @@ using System.Text.Json;
|
|||
using Duende.IdentityModel;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_supported
|
||||
public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_supported : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - token_endpoint_auth_signing_alg_values_supported";
|
||||
|
||||
|
|
@ -18,10 +17,7 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
[Trait("Category", Category)]
|
||||
public async Task token_endpoint_auth_signing_alg_values_supported_should_match_configuration()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += svcs =>
|
||||
svcs.AddIdentityServerBuilder().AddJwtBearerClientAuthentication();
|
||||
pipeline.Initialize();
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms =
|
||||
[
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
|
|
@ -43,10 +39,7 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
[Trait("Category", Category)]
|
||||
public async Task token_endpoint_auth_signing_alg_values_supported_should_default_to_rs_ps_es()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += svcs =>
|
||||
svcs.AddIdentityServerBuilder().AddJwtBearerClientAuthentication();
|
||||
pipeline.Initialize();
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
|
|
@ -95,10 +88,7 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
public async Task token_endpoint_auth_signing_alg_values_supported_should_not_be_present_if_option_is_null_or_empty(
|
||||
ICollection<string> algorithms)
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.OnPostConfigureServices += svcs =>
|
||||
svcs.AddIdentityServerBuilder().AddJwtBearerClientAuthentication();
|
||||
pipeline.Initialize();
|
||||
var pipeline = CreatePipelineWithJwtBearer();
|
||||
pipeline.Options.SupportedClientAssertionSigningAlgorithms = algorithms;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
|
|
@ -108,11 +98,4 @@ public class DiscoveryEndpointTests_token_endpoint_auth_signing_alg_values_suppo
|
|||
|
||||
data.ShouldNotContainKey(OidcConstants.Discovery.TokenEndpointAuthSigningAlgorithmsSupported);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> NullOrEmptySupportedAlgorithms() =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[] { Enumerable.Empty<string>() },
|
||||
new object[] { null }
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text.Json;
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.IntegrationTests.Common;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpoint_backchannel_authentication_request_object_auth_signing_algs_supported_Tests : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - backchannel_authentication_request_signing_alg_values_supported";
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task backchannel_authentication_request_signing_alg_values_supported_should_match_configuration()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.SupportedRequestObjectSigningAlgorithms =
|
||||
[
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
SecurityAlgorithms.EcdsaSha256
|
||||
];
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
|
||||
var algorithmsSupported = result.BackchannelAuthenticationRequestSigningAlgValuesSupported;
|
||||
|
||||
algorithmsSupported.Count().ShouldBe(2);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.RsaSsaPssSha256);
|
||||
algorithmsSupported.ShouldContain(SecurityAlgorithms.EcdsaSha256);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(NullOrEmptySupportedAlgorithms))]
|
||||
[Trait("Category", Category)]
|
||||
public async Task backchannel_authentication_request_signing_alg_values_supported_should_not_be_present_if_option_is_null_or_empty(
|
||||
ICollection<string> algorithms)
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.SupportedRequestObjectSigningAlgorithms = algorithms;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey("backchannel_authentication_request_signing_alg_values_supported");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task
|
||||
backchannel_authentication_request_signing_alg_values_supported_should_be_present_if_ciba_is_disabled()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
pipeline.Options.Endpoints.EnableBackchannelAuthenticationEndpoint = false;
|
||||
|
||||
var result = await pipeline.BackChannelClient
|
||||
.GetAsync("https://server/.well-known/openid-configuration");
|
||||
|
||||
var json = await result.Content.ReadAsStringAsync();
|
||||
var data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json);
|
||||
|
||||
data.ShouldNotContainKey("backchannel_authentication_request_signing_alg_values_supported");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", Category)]
|
||||
public async Task backchannel_authentication_request_signing_alg_values_supported_should_default_to_rs_ps_es()
|
||||
{
|
||||
var pipeline = new IdentityServerPipeline();
|
||||
pipeline.Initialize();
|
||||
|
||||
var result =
|
||||
await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(
|
||||
"https://server/.well-known/openid-configuration");
|
||||
|
||||
var algorithmsSupported = result.BackchannelAuthenticationRequestSigningAlgValuesSupported;
|
||||
|
||||
algorithmsSupported.ShouldBe([
|
||||
SecurityAlgorithms.RsaSha256,
|
||||
SecurityAlgorithms.RsaSha384,
|
||||
SecurityAlgorithms.RsaSha512,
|
||||
SecurityAlgorithms.RsaSsaPssSha384,
|
||||
SecurityAlgorithms.RsaSsaPssSha512,
|
||||
SecurityAlgorithms.RsaSsaPssSha256,
|
||||
SecurityAlgorithms.EcdsaSha256,
|
||||
SecurityAlgorithms.EcdsaSha384,
|
||||
SecurityAlgorithms.EcdsaSha512,
|
||||
], ignoreOrder: true);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ using Microsoft.IdentityModel.Tokens;
|
|||
|
||||
namespace Duende.IdentityServer.IntegrationTests.Endpoints.Discovery;
|
||||
|
||||
public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests
|
||||
public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests : DiscoveryEndpointTestsBase
|
||||
{
|
||||
private const string Category = "Discovery endpoint - request_object_signing_algs_supported";
|
||||
|
||||
|
|
@ -77,11 +77,4 @@ public class DiscoveryEndpoint_request_object_auth_signing_algs_supported_Tests
|
|||
SecurityAlgorithms.EcdsaSha512,
|
||||
], ignoreOrder: true);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> NullOrEmptySupportedAlgorithms() =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[] { Enumerable.Empty<string>() },
|
||||
new object[] { null }
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue