Browse Source

Do not use OpenIddictParameter.GetNamedParameters() to extract the mTLS endpoint aliases and validate the node type of "mtls_endpoint_aliases"

pull/2301/head
Kévin Chalet 1 year ago
parent
commit
4dfb0b79d0
  1. 28
      shared/OpenIddict.Extensions/OpenIddictHelpers.cs
  2. 54
      src/OpenIddict.Client/OpenIddictClientHandlers.Discovery.cs
  3. 14
      src/OpenIddict.Validation/OpenIddictValidationHandlers.Discovery.cs

28
shared/OpenIddict.Extensions/OpenIddictHelpers.cs

@ -1094,6 +1094,34 @@ internal static class OpenIddictHelpers
return true;
}
/// <summary>
/// Determines whether the items contained in <paramref name="element"/>
/// are of the specified <paramref name="kind"/>.
/// </summary>
/// <param name="element">The <see cref="JsonElement"/>.</param>
/// <param name="kind">The expected <see cref="JsonValueKind"/>.</param>
/// <returns>
/// <see langword="true"/> if the object doesn't contain any value or if all the items
/// are of the specified <paramref name="kind"/>, <see langword="false"/> otherwise.
/// </returns>
public static bool ValidateObjectElements(JsonElement element, JsonValueKind kind)
{
if (element.ValueKind is not JsonValueKind.Object)
{
throw new ArgumentOutOfRangeException(nameof(element));
}
foreach (var property in element.EnumerateObject())
{
if (property.Value.ValueKind != kind)
{
return false;
}
}
return true;
}
/// <summary>
/// Note: this implementation was taken from ASP.NET Core.
/// </summary>

54
src/OpenIddict.Client/OpenIddictClientHandlers.Discovery.cs

@ -137,6 +137,12 @@ public static partial class OpenIddictClientHandlers
element.ValueKind is JsonValueKind.Array &&
OpenIddictHelpers.ValidateArrayElements(element, JsonValueKind.String),
// The following parameters MUST be formatted as JSON objects and only contain string values:
Metadata.MtlsEndpointAliases
=> ((JsonElement) value) is JsonElement element &&
element.ValueKind is JsonValueKind.Object &&
OpenIddictHelpers.ValidateObjectElements(element, JsonValueKind.String),
// The following parameters MUST be formatted as booleans:
Metadata.AuthorizationResponseIssParameterSupported or
Metadata.RequirePushedAuthorizationRequests or
@ -513,15 +519,9 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.DeviceAuthorizationEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.DeviceAuthorizationEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsDeviceAuthorizationEndpoint = uri;
@ -555,15 +555,9 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.IntrospectionEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.IntrospectionEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsIntrospectionEndpoint = uri;
@ -596,15 +590,9 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.PushedAuthorizationRequestEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.PushedAuthorizationRequestEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsPushedAuthorizationEndpoint = uri;
@ -637,15 +625,9 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.RevocationEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.RevocationEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsRevocationEndpoint = uri;
@ -678,15 +660,9 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.TokenEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.TokenEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsTokenEndpoint = uri;
@ -719,15 +695,9 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.UserInfoEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.UserInfoEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsUserInfoEndpoint = uri;

14
src/OpenIddict.Validation/OpenIddictValidationHandlers.Discovery.cs

@ -99,6 +99,12 @@ public static partial class OpenIddictValidationHandlers
element.ValueKind is JsonValueKind.Array &&
OpenIddictHelpers.ValidateArrayElements(element, JsonValueKind.String),
// The following parameters MUST be formatted as JSON objects and only contain string values:
Metadata.MtlsEndpointAliases
=> ((JsonElement) value) is JsonElement element &&
element.ValueKind is JsonValueKind.Object &&
OpenIddictHelpers.ValidateObjectElements(element, JsonValueKind.String),
// Parameters that are not in the well-known list can be of any type.
_ => true
};
@ -331,15 +337,9 @@ public static partial class OpenIddictValidationHandlers
throw new ArgumentNullException(nameof(context));
}
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
if (aliases is not { Count: > 0 })
{
return default;
}
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
var endpoint = (string?) aliases[Metadata.IntrospectionEndpoint];
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.IntrospectionEndpoint];
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
{
context.Configuration.MtlsIntrospectionEndpoint = uri;

Loading…
Cancel
Save