Skip to content

Commit 4dfb0b7

Browse files
committed
Do not use OpenIddictParameter.GetNamedParameters() to extract the mTLS endpoint aliases and validate the node type of "mtls_endpoint_aliases"
1 parent fab284f commit 4dfb0b7

File tree

3 files changed

+47
-49
lines changed

3 files changed

+47
-49
lines changed

shared/OpenIddict.Extensions/OpenIddictHelpers.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,34 @@ public static bool ValidateArrayElements(JsonElement element, JsonValueKind kind
10941094
return true;
10951095
}
10961096

1097+
/// <summary>
1098+
/// Determines whether the items contained in <paramref name="element"/>
1099+
/// are of the specified <paramref name="kind"/>.
1100+
/// </summary>
1101+
/// <param name="element">The <see cref="JsonElement"/>.</param>
1102+
/// <param name="kind">The expected <see cref="JsonValueKind"/>.</param>
1103+
/// <returns>
1104+
/// <see langword="true"/> if the object doesn't contain any value or if all the items
1105+
/// are of the specified <paramref name="kind"/>, <see langword="false"/> otherwise.
1106+
/// </returns>
1107+
public static bool ValidateObjectElements(JsonElement element, JsonValueKind kind)
1108+
{
1109+
if (element.ValueKind is not JsonValueKind.Object)
1110+
{
1111+
throw new ArgumentOutOfRangeException(nameof(element));
1112+
}
1113+
1114+
foreach (var property in element.EnumerateObject())
1115+
{
1116+
if (property.Value.ValueKind != kind)
1117+
{
1118+
return false;
1119+
}
1120+
}
1121+
1122+
return true;
1123+
}
1124+
10971125
/// <summary>
10981126
/// Note: this implementation was taken from ASP.NET Core.
10991127
/// </summary>

src/OpenIddict.Client/OpenIddictClientHandlers.Discovery.cs

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ Metadata.ScopesSupported or
137137
element.ValueKind is JsonValueKind.Array &&
138138
OpenIddictHelpers.ValidateArrayElements(element, JsonValueKind.String),
139139

140+
// The following parameters MUST be formatted as JSON objects and only contain string values:
141+
Metadata.MtlsEndpointAliases
142+
=> ((JsonElement) value) is JsonElement element &&
143+
element.ValueKind is JsonValueKind.Object &&
144+
OpenIddictHelpers.ValidateObjectElements(element, JsonValueKind.String),
145+
140146
// The following parameters MUST be formatted as booleans:
141147
Metadata.AuthorizationResponseIssParameterSupported or
142148
Metadata.RequirePushedAuthorizationRequests or
@@ -513,15 +519,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
513519
throw new ArgumentNullException(nameof(context));
514520
}
515521

516-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
517-
if (aliases is not { Count: > 0 })
518-
{
519-
return default;
520-
}
521-
522522
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
523523
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
524-
var endpoint = (string?) aliases[Metadata.DeviceAuthorizationEndpoint];
524+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.DeviceAuthorizationEndpoint];
525525
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
526526
{
527527
context.Configuration.MtlsDeviceAuthorizationEndpoint = uri;
@@ -555,15 +555,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
555555
throw new ArgumentNullException(nameof(context));
556556
}
557557

558-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
559-
if (aliases is not { Count: > 0 })
560-
{
561-
return default;
562-
}
563-
564558
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
565559
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
566-
var endpoint = (string?) aliases[Metadata.IntrospectionEndpoint];
560+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.IntrospectionEndpoint];
567561
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
568562
{
569563
context.Configuration.MtlsIntrospectionEndpoint = uri;
@@ -596,15 +590,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
596590
throw new ArgumentNullException(nameof(context));
597591
}
598592

599-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
600-
if (aliases is not { Count: > 0 })
601-
{
602-
return default;
603-
}
604-
605593
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
606594
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
607-
var endpoint = (string?) aliases[Metadata.PushedAuthorizationRequestEndpoint];
595+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.PushedAuthorizationRequestEndpoint];
608596
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
609597
{
610598
context.Configuration.MtlsPushedAuthorizationEndpoint = uri;
@@ -637,15 +625,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
637625
throw new ArgumentNullException(nameof(context));
638626
}
639627

640-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
641-
if (aliases is not { Count: > 0 })
642-
{
643-
return default;
644-
}
645-
646628
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
647629
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
648-
var endpoint = (string?) aliases[Metadata.RevocationEndpoint];
630+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.RevocationEndpoint];
649631
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
650632
{
651633
context.Configuration.MtlsRevocationEndpoint = uri;
@@ -678,15 +660,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
678660
throw new ArgumentNullException(nameof(context));
679661
}
680662

681-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
682-
if (aliases is not { Count: > 0 })
683-
{
684-
return default;
685-
}
686-
687663
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
688664
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
689-
var endpoint = (string?) aliases[Metadata.TokenEndpoint];
665+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.TokenEndpoint];
690666
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
691667
{
692668
context.Configuration.MtlsTokenEndpoint = uri;
@@ -719,15 +695,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
719695
throw new ArgumentNullException(nameof(context));
720696
}
721697

722-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
723-
if (aliases is not { Count: > 0 })
724-
{
725-
return default;
726-
}
727-
728698
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
729699
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
730-
var endpoint = (string?) aliases[Metadata.UserInfoEndpoint];
700+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.UserInfoEndpoint];
731701
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
732702
{
733703
context.Configuration.MtlsUserInfoEndpoint = uri;

src/OpenIddict.Validation/OpenIddictValidationHandlers.Discovery.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ Metadata.IntrospectionEndpoint or
9999
element.ValueKind is JsonValueKind.Array &&
100100
OpenIddictHelpers.ValidateArrayElements(element, JsonValueKind.String),
101101

102+
// The following parameters MUST be formatted as JSON objects and only contain string values:
103+
Metadata.MtlsEndpointAliases
104+
=> ((JsonElement) value) is JsonElement element &&
105+
element.ValueKind is JsonValueKind.Object &&
106+
OpenIddictHelpers.ValidateObjectElements(element, JsonValueKind.String),
107+
102108
// Parameters that are not in the well-known list can be of any type.
103109
_ => true
104110
};
@@ -331,15 +337,9 @@ public ValueTask HandleAsync(HandleConfigurationResponseContext context)
331337
throw new ArgumentNullException(nameof(context));
332338
}
333339

334-
var aliases = context.Response[Metadata.MtlsEndpointAliases]?.GetNamedParameters();
335-
if (aliases is not { Count: > 0 })
336-
{
337-
return default;
338-
}
339-
340340
// Note: as recommended by the specification, values present in the "mtls_endpoint_aliases" node
341341
// that can't be recognized as OAuth 2.0 endpoints or are not valid URIs are simply ignored.
342-
var endpoint = (string?) aliases[Metadata.IntrospectionEndpoint];
342+
var endpoint = (string?) context.Response[Metadata.MtlsEndpointAliases]?[Metadata.IntrospectionEndpoint];
343343
if (Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) && !OpenIddictHelpers.IsImplicitFileUri(uri))
344344
{
345345
context.Configuration.MtlsIntrospectionEndpoint = uri;

0 commit comments

Comments
 (0)