Browse Source

Replace references to "URL" by "URI" when resource identifiers are not required to be resource locators

pull/1615/head
Kévin Chalet 3 years ago
parent
commit
8c14d4e3e9
  1. 22
      gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs
  2. 2
      sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/AuthenticationController.cs
  3. 2
      sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs
  4. 2
      sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthenticationController.cs
  5. 2
      sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs
  6. 2
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs
  7. 2
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs
  8. 28
      shared/OpenIddict.Extensions/Helpers/OpenIddictHelpers.cs
  9. 10
      src/OpenIddict.Abstractions/Caches/IOpenIddictApplicationCache.cs
  10. 4
      src/OpenIddict.Abstractions/Descriptors/OpenIddictApplicationDescriptor.cs
  11. 20
      src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs
  12. 74
      src/OpenIddict.Abstractions/OpenIddictResources.resx
  13. 14
      src/OpenIddict.Abstractions/Primitives/OpenIddictConfiguration.cs
  14. 26
      src/OpenIddict.Abstractions/Stores/IOpenIddictApplicationStore.cs
  15. 4
      src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs
  16. 6
      src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs
  17. 4
      src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs
  18. 6
      src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs
  19. 2
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpExtensions.cs
  20. 8
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlerFilters.cs
  21. 2
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs
  22. 4
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs
  23. 30
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs
  24. 2
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs
  25. 4
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs
  26. 4
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  27. 6
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml
  28. 4
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xsd
  29. 84
      src/OpenIddict.Client/OpenIddictClientBuilder.cs
  30. 12
      src/OpenIddict.Client/OpenIddictClientConfiguration.cs
  31. 14
      src/OpenIddict.Client/OpenIddictClientEvents.cs
  32. 4
      src/OpenIddict.Client/OpenIddictClientHandlers.Authentication.cs
  33. 52
      src/OpenIddict.Client/OpenIddictClientHandlers.Discovery.cs
  34. 19
      src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
  35. 4
      src/OpenIddict.Client/OpenIddictClientHandlers.Session.cs
  36. 62
      src/OpenIddict.Client/OpenIddictClientHandlers.cs
  37. 2
      src/OpenIddict.Client/OpenIddictClientOptions.cs
  38. 22
      src/OpenIddict.Client/OpenIddictClientRegistration.cs
  39. 2
      src/OpenIddict.Client/OpenIddictClientRetriever.cs
  40. 112
      src/OpenIddict.Client/OpenIddictClientService.cs
  41. 28
      src/OpenIddict.Core/Caches/OpenIddictApplicationCache.cs
  42. 130
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  43. 4
      src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkApplication.cs
  44. 56
      src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
  45. 4
      src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreApplication.cs
  46. 56
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
  47. 4
      src/OpenIddict.MongoDb.Models/OpenIddictMongoDbApplication.cs
  48. 28
      src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs
  49. 2
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreBuilder.cs
  50. 4
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs
  51. 4
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Device.cs
  52. 4
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs
  53. 2
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs
  54. 2
      src/OpenIddict.Server.Owin/OpenIddictServerOwinBuilder.cs
  55. 4
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs
  56. 4
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Device.cs
  57. 4
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs
  58. 2
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs
  59. 372
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  60. 6
      src/OpenIddict.Server/OpenIddictServerConfiguration.cs
  61. 18
      src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
  62. 18
      src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs
  63. 18
      src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
  64. 2
      src/OpenIddict.Server/OpenIddictServerEvents.cs
  65. 18
      src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
  66. 8
      src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs
  67. 6
      src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
  68. 12
      src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
  69. 23
      src/OpenIddict.Server/OpenIddictServerHandlers.cs
  70. 2
      src/OpenIddict.Server/OpenIddictServerOptions.cs
  71. 2
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreBuilder.cs
  72. 2
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs
  73. 2
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinBuilder.cs
  74. 2
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs
  75. 2
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpExtensions.cs
  76. 8
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlerFilters.cs
  77. 2
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs
  78. 30
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
  79. 28
      src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
  80. 31
      src/OpenIddict.Validation/OpenIddictValidationConfiguration.cs
  81. 6
      src/OpenIddict.Validation/OpenIddictValidationEvents.cs
  82. 24
      src/OpenIddict.Validation/OpenIddictValidationHandlers.Discovery.cs
  83. 2
      src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
  84. 8
      src/OpenIddict.Validation/OpenIddictValidationOptions.cs
  85. 74
      src/OpenIddict.Validation/OpenIddictValidationService.cs
  86. 12
      test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs
  87. 10
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs
  88. 8
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs
  89. 4
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Session.cs
  90. 4
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
  91. 12
      test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs
  92. 164
      test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs
  93. 10
      test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTestClient.cs

22
gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs

@ -175,31 +175,31 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// <summary>
/// Sets the redirection URI, if applicable.
/// </summary>
/// <param name=""address"">The redirection URI.</param>
/// <param name=""uri"">The redirection URI.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
public {{ provider.name }} SetRedirectUri(Uri address)
public {{ provider.name }} SetRedirectUri(Uri uri)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
return Configure(options => options.RedirectUri = address);
return Configure(options => options.RedirectUri = uri);
}
/// <summary>
/// Sets the redirection URI, if applicable.
/// </summary>
/// <param name=""address"">The redirection URI.</param>
/// <param name=""uri"">The redirection URI.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
public {{ provider.name }} SetRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string address)
public {{ provider.name }} SetRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
return SetRedirectUri(new Uri(address, UriKind.RelativeOrAbsolute));
return SetRedirectUri(new Uri(uri, UriKind.RelativeOrAbsolute));
}
/// <summary>
@ -813,7 +813,7 @@ public sealed partial class OpenIddictClientWebIntegrationOptions
public string? ClientSecret { get; set; }
/// <summary>
/// Gets or sets the redirection URL.
/// Gets or sets the redirect URI.
/// </summary>
public Uri? RedirectUri { get; set; }

2
sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/AuthenticationController.cs

@ -216,7 +216,7 @@ namespace OpenIddict.Sandbox.AspNet.Client.Controllers
var properties = new AuthenticationProperties(result.Properties.Dictionary
.Where(item => item switch
{
// Preserve the redirect URL.
// Preserve the return URL.
{ Key: ".redirect" } => true,
// If needed, the tokens returned by the authorization server can be stored in the authentication cookie.

2
sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs

@ -69,7 +69,7 @@ namespace OpenIddict.Sandbox.AspNet.Client
// Enable the redirection endpoint needed to handle the callback stage.
//
// Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint
// address per provider, unless all the registered providers support returning an "iss"
// URI per provider, unless all the registered providers support returning a special "iss"
// parameter containing their URL as part of authorization responses. For more information,
// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4.
options.SetRedirectionEndpointUris(

2
sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthenticationController.cs

@ -109,7 +109,7 @@ namespace OpenIddict.Sandbox.AspNet.Server.Controllers
var properties = new AuthenticationProperties(result.Properties.Dictionary
.Where(item => item switch
{
// Preserve the redirect URL.
// Preserve the return URL.
{ Key: ".redirect" } => true,
// If needed, the tokens returned by the authorization server can be stored in the authentication cookie.

2
sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs

@ -154,7 +154,7 @@ namespace OpenIddict.Sandbox.AspNet.Server
// Enable the redirection endpoint needed to handle the callback stage.
//
// Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint
// address per provider, unless all the registered providers support returning an "iss"
// URI per provider, unless all the registered providers support returning a special "iss"
// parameter containing their URL as part of authorization responses. For more information,
// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4.
options.SetRedirectionEndpointUris("callback/login/github");

2
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs

@ -77,7 +77,7 @@ public class Startup
// Enable the redirection endpoint needed to handle the callback stage.
//
// Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint
// address per provider, unless all the registered providers support returning an "iss"
// URI per provider, unless all the registered providers support returning a special "iss"
// parameter containing their URL as part of authorization responses. For more information,
// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4.
options.SetRedirectionEndpointUris(

2
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs

@ -71,7 +71,7 @@ public class Startup
// Enable the redirection endpoint needed to handle the callback stage.
//
// Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint
// address per provider, unless all the registered providers support returning an "iss"
// URI per provider, unless all the registered providers support returning a special "iss"
// parameter containing their URL as part of authorization responses. For more information,
// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4.
options.SetRedirectionEndpointUris("callback/login/github");

28
shared/OpenIddict.Extensions/Helpers/OpenIddictHelpers.cs

@ -172,18 +172,18 @@ internal static class OpenIddictHelpers
/// <summary>
/// Adds a query string parameter to the specified <see cref="Uri"/>.
/// </summary>
/// <param name="address">The address, to which the query string parameter will be appended.</param>
/// <param name="uri">The URI to which the query string parameter will be appended.</param>
/// <param name="name">The name of the query string parameter to append.</param>
/// <param name="value">The value of the query string parameter to append.</param>
/// <returns>The final <see cref="Uri"/> instance, with the specified parameter appended.</returns>
public static Uri AddQueryStringParameter(Uri address, string name, string? value)
public static Uri AddQueryStringParameter(Uri uri, string name, string? value)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
var builder = new StringBuilder(address.Query);
var builder = new StringBuilder(uri.Query);
if (builder.Length > 0)
{
builder.Append('&');
@ -197,22 +197,22 @@ internal static class OpenIddictHelpers
builder.Append(Uri.EscapeDataString(value));
}
return new UriBuilder(address) { Query = builder.ToString() }.Uri;
return new UriBuilder(uri) { Query = builder.ToString() }.Uri;
}
/// <summary>
/// Adds query string parameters to the specified <see cref="Uri"/>.
/// </summary>
/// <param name="address">The address, to which the query string parameters will be appended.</param>
/// <param name="uri">The URI to which the query string parameters will be appended.</param>
/// <param name="parameters">The query string parameters to append.</param>
/// <returns>The final <see cref="Uri"/> instance, with the specified parameters appended.</returns>
/// <exception cref="ArgumentNullException"><paramref name="address"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="parameters"/> is <see langword="null"/>.</exception>
public static Uri AddQueryStringParameters(Uri address, IReadOnlyDictionary<string, StringValues> parameters)
public static Uri AddQueryStringParameters(Uri uri, IReadOnlyDictionary<string, StringValues> parameters)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (parameters is null)
@ -222,10 +222,10 @@ internal static class OpenIddictHelpers
if (parameters.Count is 0)
{
return address;
return uri;
}
var builder = new StringBuilder(address.Query);
var builder = new StringBuilder(uri.Query);
foreach (var parameter in parameters)
{
@ -263,7 +263,7 @@ internal static class OpenIddictHelpers
}
}
return new UriBuilder(address) { Query = builder.ToString() }.Uri;
return new UriBuilder(uri) { Query = builder.ToString() }.Uri;
}
/// <summary>

10
src/OpenIddict.Abstractions/Caches/IOpenIddictApplicationCache.cs

@ -45,22 +45,22 @@ public interface IOpenIddictApplicationCache<TApplication> where TApplication :
ValueTask<TApplication?> FindByIdAsync(string identifier, CancellationToken cancellationToken);
/// <summary>
/// Retrieves all the applications associated with the specified redirect_uri.
/// Retrieves all the applications associated with the specified post_logout_redirect_uri.
/// </summary>
/// <param name="address">The redirect_uri associated with the applications.</param>
/// <param name="uri">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified redirect_uri.</returns>
IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken);
/// <summary>
/// Retrieves all the applications associated with the specified redirect_uri.
/// </summary>
/// <param name="address">The redirect_uri associated with the applications.</param>
/// <param name="uri">The redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified redirect_uri.</returns>
IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken);
/// <summary>
/// Removes the specified application from the cache.

4
src/OpenIddict.Abstractions/Descriptors/OpenIddictApplicationDescriptor.cs

@ -41,7 +41,7 @@ public class OpenIddictApplicationDescriptor
public HashSet<string> Permissions { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets the logout callback URLs associated with the application.
/// Gets the post-logout redirect URIs associated with the application.
/// </summary>
public HashSet<Uri> PostLogoutRedirectUris { get; } = new();
@ -51,7 +51,7 @@ public class OpenIddictApplicationDescriptor
public Dictionary<string, JsonElement> Properties { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets the callback URLs associated with the application.
/// Gets the redirect URIs associated with the application.
/// </summary>
public HashSet<Uri> RedirectUris { get; } = new();

20
src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs

@ -115,20 +115,20 @@ public interface IOpenIddictApplicationManager
/// <summary>
/// Retrieves all the applications associated with the specified post_logout_redirect_uri.
/// </summary>
/// <param name="address">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="uri">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified post_logout_redirect_uri.</returns>
IAsyncEnumerable<object> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default);
/// <summary>
/// Retrieves all the applications associated with the specified redirect_uri.
/// </summary>
/// <param name="address">The redirect_uri associated with the applications.</param>
/// <param name="uri">The redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified redirect_uri.</returns>
IAsyncEnumerable<object> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default);
/// <summary>
/// Executes the specified query and returns the first element.
@ -264,7 +264,7 @@ public interface IOpenIddictApplicationManager
ValueTask<ImmutableArray<string>> GetPermissionsAsync(object application, CancellationToken cancellationToken = default);
/// <summary>
/// Retrieves the logout callback addresses associated with an application.
/// Retrieves the post-logout redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
@ -286,7 +286,7 @@ public interface IOpenIddictApplicationManager
ValueTask<ImmutableDictionary<string, JsonElement>> GetPropertiesAsync(object application, CancellationToken cancellationToken = default);
/// <summary>
/// Retrieves the callback addresses associated with an application.
/// Retrieves the redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
@ -457,7 +457,7 @@ public interface IOpenIddictApplicationManager
/// Validates the post_logout_redirect_uri to ensure it's associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="address">The address that should be compared to one of the post_logout_redirect_uri stored in the database.</param>
/// <param name="uri">The URI that should be compared to one of the post_logout_redirect_uri stored in the database.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <remarks>Note: if no client_id parameter is specified in logout requests, this method may not be called.</remarks>
/// <returns>
@ -465,18 +465,18 @@ public interface IOpenIddictApplicationManager
/// whose result returns a boolean indicating whether the post_logout_redirect_uri was valid.
/// </returns>
ValueTask<bool> ValidatePostLogoutRedirectUriAsync(object application,
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default);
/// <summary>
/// Validates the redirect_uri to ensure it's associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="address">The address that should be compared to one of the redirect_uri stored in the database.</param>
/// <param name="uri">The URI that should be compared to one of the redirect_uri stored in the database.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation,
/// whose result returns a boolean indicating whether the redirect_uri was valid.
/// </returns>
ValueTask<bool> ValidateRedirectUriAsync(object application,
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default);
}

74
src/OpenIddict.Abstractions/OpenIddictResources.resx

@ -193,7 +193,7 @@ Alternatively, you can disable the built-in database-based server features by en
<value>A token cannot be created from a null principal.</value>
</data>
<data name="ID0023" xml:space="preserve">
<value>The issuer must be a non-null, non-empty absolute URL.</value>
<value>The issuer must be a non-null, non-empty absolute URI.</value>
</data>
<data name="ID0024" xml:space="preserve">
<value>A sign-out response cannot be returned from this endpoint.</value>
@ -367,7 +367,7 @@ Consider using 'options.AddSigningCredentials(SigningCredentials)' instead.</val
<value>The grant type cannot be null or empty.</value>
</data>
<data name="ID0072" xml:space="preserve">
<value>Endpoint addresses must be valid URLs.</value>
<value>Endpoint URIs must be valid URIs.</value>
</data>
<data name="ID0073" xml:space="preserve">
<value>Claims cannot be null or empty.</value>
@ -394,7 +394,7 @@ Consider using 'options.AddSigningCredentials(SigningCredentials)' instead.</val
<value>The verification endpoint must be enabled to use the device flow.</value>
</data>
<data name="ID0081" xml:space="preserve">
<value>Endpoint addresses cannot start with '{0}'.</value>
<value>Endpoint URIs cannot start with '{0}'.</value>
</data>
<data name="ID0082" xml:space="preserve">
<value>Dependency injection support must be enabled in Quartz.NET when using the OpenIddict integration.
@ -550,7 +550,7 @@ To register the server services, use 'services.AddOpenIddict().AddServer()'.</va
<value>The base URI or request URI cannot be retrieved from the request context or are now valid absolute URIs.</value>
</data>
<data name="ID0128" xml:space="preserve">
<value>An OAuth 2.0/OpenID Connect server configuration or an issuer address must be registered.
<value>An OAuth 2.0/OpenID Connect server configuration or an issuer URI must be registered.
To use a local OpenIddict server, reference the 'OpenIddict.Validation.ServerIntegration' package and call 'services.AddOpenIddict().AddValidation().UseLocalServer()' to import the server settings.
To use a remote server, reference the 'OpenIddict.Validation.SystemNetHttp' package and call 'services.AddOpenIddict().AddValidation().UseSystemNetHttp()' and 'services.AddOpenIddict().AddValidation().SetIssuer()' to use server discovery.
Alternatively, you can register a static server configuration by calling 'services.AddOpenIddict().AddValidation().SetConfiguration()'.</value>
@ -560,7 +560,7 @@ Alternatively, you can register a static server configuration by calling 'servic
Reference the 'OpenIddict.Validation.SystemNetHttp' package and call 'services.AddOpenIddict().AddValidation().UseSystemNetHttp()' to register the default System.Net.Http-based integration.</value>
</data>
<data name="ID0130" xml:space="preserve">
<value>The issuer or the metadata address must be set when using introspection.</value>
<value>The issuer or the configuration endpoint URI must be set when using introspection.</value>
</data>
<data name="ID0131" xml:space="preserve">
<value>The client identifier cannot be null or empty when using introspection.</value>
@ -579,10 +579,10 @@ Reference the 'OpenIddict.Validation.SystemNetHttp' package and call 'services.A
Reference the 'OpenIddict.Validation.SystemNetHttp' package and call 'services.AddOpenIddict().AddValidation().UseSystemNetHttp()' to register the default System.Net.Http-based integration.</value>
</data>
<data name="ID0136" xml:space="preserve">
<value>The authority must be provided and must be an absolute URL.</value>
<value>The issuer must be provided and must be an absolute URI.</value>
</data>
<data name="ID0137" xml:space="preserve">
<value>The authority cannot contain a fragment or a query string.</value>
<value>The issuer cannot contain a fragment or a query string.</value>
</data>
<data name="ID0138" xml:space="preserve">
<value>The event handler of type '{0}' couldn't be resolved.
@ -603,10 +603,10 @@ To register the OpenIddict core services, reference the 'OpenIddict.Core' packag
To register the OpenIddict core services, reference the 'OpenIddict.Core' package and call 'services.AddOpenIddict().AddCore()' from 'ConfigureServices'.</value>
</data>
<data name="ID0143" xml:space="preserve">
<value>The address cannot be null or empty.</value>
<value>The URI cannot be null or empty.</value>
</data>
<data name="ID0144" xml:space="preserve">
<value>The address must be a valid absolute URI.</value>
<value>The URI must be a valid absolute URI.</value>
</data>
<data name="ID0145" xml:space="preserve">
<value>The server configuration couldn't be retrieved.</value>
@ -857,10 +857,10 @@ To register the validation services, use 'services.AddOpenIddict().AddValidation
<value>The requirement name cannot be null or empty.</value>
</data>
<data name="ID0213" xml:space="preserve">
<value>Callback URLs cannot be null or empty.</value>
<value>Callback URIs cannot be null or empty.</value>
</data>
<data name="ID0214" xml:space="preserve">
<value>Callback URLs must be valid absolute URLs.</value>
<value>Callback URIs must be valid absolute URIs.</value>
</data>
<data name="ID0215" xml:space="preserve">
<value>One or more validation error(s) occurred while trying to update an existing application:</value>
@ -1111,7 +1111,7 @@ To register the OpenIddict core services, reference the 'OpenIddict.Core' packag
<value>The context type associated with the specified descriptor doesn't match the context type of this builder.</value>
</data>
<data name="ID0285" xml:space="preserve">
<value>Endpoint addresses must be unique across endpoints.</value>
<value>Endpoint URIs must be unique across endpoints.</value>
</data>
<data name="ID0286" xml:space="preserve">
<value>The specified principal doesn't contain a valid claims-based identity.</value>
@ -1180,7 +1180,7 @@ To apply redirection responses, create a class implementing 'IOpenIddictClientHa
<value>No issuer was specified in the challenge properties. When multiple clients are registered, an issuer (or a provider name) must be specified in the challenge properties.</value>
</data>
<data name="ID0306" xml:space="preserve">
<value>The specified issuer is not a valid or absolute URL.</value>
<value>The specified issuer is not a valid or absolute URI.</value>
</data>
<data name="ID0307" xml:space="preserve">
<value>The issuer extracted from the server configuration metadata doesn't match the expected value.</value>
@ -1484,7 +1484,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>The mandatory '{0}' parameter is missing.</value>
</data>
<data name="ID2030" xml:space="preserve">
<value>The '{0}' parameter must be a valid absolute URL.</value>
<value>The '{0}' parameter must be a valid absolute URI.</value>
</data>
<data name="ID2031" xml:space="preserve">
<value>The '{0}' parameter must not include a fragment.</value>
@ -1577,10 +1577,10 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>A scope with the same name already exists.</value>
</data>
<data name="ID2061" xml:space="preserve">
<value>Callback URLs cannot be null or empty.</value>
<value>Callback URIs cannot be null or empty.</value>
</data>
<data name="ID2062" xml:space="preserve">
<value>Callback URLs must be valid absolute URLs.</value>
<value>Callback URIs must be valid absolute URIs.</value>
</data>
<data name="ID2063" xml:space="preserve">
<value>This client application is not allowed to use the token endpoint.</value>
@ -1610,7 +1610,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>The specified refresh token cannot be used by this client application.</value>
</data>
<data name="ID2072" xml:space="preserve">
<value>The specified '{0}' parameter doesn't match the client redirection address the authorization code was initially sent to.</value>
<value>The specified '{0}' parameter doesn't match the client redirection URI the authorization code was initially sent to.</value>
</data>
<data name="ID2073" xml:space="preserve">
<value>The '{0}' parameter cannot be used when no '{1}' was specified in the authorization request.</value>
@ -1694,7 +1694,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>No JWKS endpoint could be found in the server configuration.</value>
</data>
<data name="ID2100" xml:space="preserve">
<value>A server configuration containing an invalid '{0}' URL was returned.</value>
<value>A server configuration containing an invalid '{0}' URI was returned.</value>
</data>
<data name="ID2102" xml:space="preserve">
<value>The JWKS document didn't contain a valid '{0}' node with at least one key.</value>
@ -1736,7 +1736,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>A client secret cannot be associated with a public application.</value>
</data>
<data name="ID2115" xml:space="preserve">
<value>Callback URLs cannot contain a fragment.</value>
<value>Callback URIs cannot contain a fragment.</value>
</data>
<data name="ID2116" xml:space="preserve">
<value>The authorization type cannot be null or empty.</value>
@ -1793,7 +1793,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>The '{0}' claim returned in the specified userinfo response/token doesn't match the expected value.</value>
</data>
<data name="ID2134" xml:space="preserve">
<value>Callback URLs cannot contain an "{0}" parameter.</value>
<value>Callback URIs cannot contain an "{0}" parameter.</value>
</data>
<data name="ID2135" xml:space="preserve">
<value>The '{0}' parameter must not include a '{1}' component.</value>
@ -1805,7 +1805,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>An invalid JSON response was returned by the remote HTTP server.</value>
</data>
<data name="ID2138" xml:space="preserve">
<value>The current address doesn't match the address of the redirection endpoint selected during the initial authorization request.</value>
<value>The current URI doesn't match the URI of the redirection endpoint selected during the initial authorization request.</value>
</data>
<data name="ID2139" xml:space="preserve">
<value>The specified state token has already been redeemed.</value>
@ -1925,7 +1925,7 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<value>EC-based keys should have a non-null OID raw value or friendly name.</value>
</data>
<data name="ID4013" xml:space="preserve">
<value>The issuer should be a valid absolute URL at this point.</value>
<value>The issuer should be a valid absolute URI at this point.</value>
</data>
<data name="ID4014" xml:space="preserve">
<value>The username shouldn't be null or empty at this point.</value>
@ -1998,10 +1998,10 @@ The principal used to create the token contained the following claims: {Claims}.
<value>The authorization request was rejected because the mandatory '{Parameter}' parameter was missing.</value>
</data>
<data name="ID6034" xml:space="preserve">
<value>The authorization request was rejected because the '{Parameter}' parameter wasn't a valid absolute URL: {RedirectUri}.</value>
<value>The authorization request was rejected because the '{Parameter}' parameter wasn't a valid absolute URI: {RedirectUri}.</value>
</data>
<data name="ID6035" xml:space="preserve">
<value>The authorization request was rejected because the '{Parameter}' contained a URL fragment: {RedirectUri}.</value>
<value>The authorization request was rejected because the '{Parameter}' contained a URI fragment: {RedirectUri}.</value>
</data>
<data name="ID6036" xml:space="preserve">
<value>The authorization request was rejected because the '{ResponseType}' response type is not supported.</value>
@ -2055,7 +2055,7 @@ The principal used to create the token contained the following claims: {Claims}.
<value>The authorization request was rejected because the application '{ClientId}' was not allowed to use the '{Scope}' scope.</value>
</data>
<data name="ID6053" xml:space="preserve">
<value>The request address matched a server endpoint: {Endpoint}.</value>
<value>The request URI matched a server endpoint: {Endpoint}.</value>
</data>
<data name="ID6054" xml:space="preserve">
<value>The device request was successfully extracted: {Request}.</value>
@ -2274,10 +2274,10 @@ The principal used to create the token contained the following claims: {Claims}.
<value>The logout request was successfully validated.</value>
</data>
<data name="ID6126" xml:space="preserve">
<value>The logout request was rejected because the '{Parameter}' parameter wasn't a valid absolute URL: {PostLogoutRedirectUri}.</value>
<value>The logout request was rejected because the '{Parameter}' parameter wasn't a valid absolute URI: {PostLogoutRedirectUri}.</value>
</data>
<data name="ID6127" xml:space="preserve">
<value>The logout request was rejected because the '{Parameter}' contained a URL fragment: {PostLogoutRedirectUri}.</value>
<value>The logout request was rejected because the '{Parameter}' contained a URI fragment: {PostLogoutRedirectUri}.</value>
</data>
<data name="ID6128" xml:space="preserve">
<value>The logout request was rejected because the specified post_logout_redirect_uri was invalid: {PostLogoutRedirectUri}.</value>
@ -2455,34 +2455,34 @@ This may indicate that the hashed entry is corrupted or malformed.</value>
<value>An unsupported {StatusCode} response was returned by the remote HTTP server: {ContentType} {Payload}.</value>
</data>
<data name="ID6186" xml:space="preserve">
<value>The configuration request was successfully sent to {Address}: {Request}.</value>
<value>The configuration request was successfully sent to {Uri}: {Request}.</value>
</data>
<data name="ID6187" xml:space="preserve">
<value>The configuration response returned by {Address} was successfully extracted: {Response}.</value>
<value>The configuration response returned by {Uri} was successfully extracted: {Response}.</value>
</data>
<data name="ID6188" xml:space="preserve">
<value>The cryptography request was successfully sent to {Address}: {Request}.</value>
<value>The cryptography request was successfully sent to {Uri}: {Request}.</value>
</data>
<data name="ID6189" xml:space="preserve">
<value>The cryptography response returned by {Address} was successfully extracted: {Response}.</value>
<value>The cryptography response returned by {Uri} was successfully extracted: {Response}.</value>
</data>
<data name="ID6190" xml:space="preserve">
<value>The introspection request was successfully sent to {Address}: {Request}.</value>
<value>The introspection request was successfully sent to {Uri}: {Request}.</value>
</data>
<data name="ID6191" xml:space="preserve">
<value>The introspection response returned by {Address} was successfully extracted: {Response}.</value>
<value>The introspection response returned by {Uri} was successfully extracted: {Response}.</value>
</data>
<data name="ID6192" xml:space="preserve">
<value>The token request was successfully sent to {Address}: {Request}.</value>
<value>The token request was successfully sent to {Uri}: {Request}.</value>
</data>
<data name="ID6193" xml:space="preserve">
<value>The token response returned by {Address} was successfully extracted: {Response}.</value>
<value>The token response returned by {Uri} was successfully extracted: {Response}.</value>
</data>
<data name="ID6194" xml:space="preserve">
<value>The userinfo request was successfully sent to {Address}: {Request}.</value>
<value>The userinfo request was successfully sent to {Uri}: {Request}.</value>
</data>
<data name="ID6195" xml:space="preserve">
<value>The userinfo response returned by {Address} was successfully extracted: {Response}.</value>
<value>The userinfo response returned by {Uri} was successfully extracted: {Response}.</value>
</data>
<data name="ID6196" xml:space="preserve">
<value>The logout request was rejected because the client application was not found: '{ClientId}'.</value>

14
src/OpenIddict.Abstractions/Primitives/OpenIddictConfiguration.cs

@ -17,7 +17,7 @@ namespace OpenIddict.Abstractions;
public sealed class OpenIddictConfiguration
{
/// <summary>
/// Gets or sets the address of the authorization endpoint.
/// Gets or sets the URI of the authorization endpoint.
/// </summary>
public Uri? AuthorizationEndpoint { get; set; }
@ -32,7 +32,7 @@ public sealed class OpenIddictConfiguration
public HashSet<string> CodeChallengeMethodsSupported { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the address of the end session endpoint.
/// Gets or sets the URI of the end session endpoint.
/// </summary>
public Uri? EndSessionEndpoint { get; set; }
@ -42,7 +42,7 @@ public sealed class OpenIddictConfiguration
public HashSet<string> GrantTypesSupported { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the address of the introspection endpoint.
/// Gets or sets the URI of the introspection endpoint.
/// </summary>
public Uri? IntrospectionEndpoint { get; set; }
@ -52,7 +52,7 @@ public sealed class OpenIddictConfiguration
public HashSet<string> IntrospectionEndpointAuthMethodsSupported { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the address of the issuer.
/// Gets or sets the URI of the issuer.
/// </summary>
public Uri? Issuer { get; set; }
@ -62,7 +62,7 @@ public sealed class OpenIddictConfiguration
public JsonWebKeySet? JsonWebKeySet { get; set; }
/// <summary>
/// Gets or sets the address of the JWKS endpoint.
/// Gets or sets the URI of the JWKS endpoint.
/// </summary>
public Uri? JwksUri { get; set; }
@ -92,7 +92,7 @@ public sealed class OpenIddictConfiguration
public List<SecurityKey> SigningKeys { get; } = new();
/// <summary>
/// Gets or sets the address of the token endpoint.
/// Gets or sets the URI of the token endpoint.
/// </summary>
public Uri? TokenEndpoint { get; set; }
@ -102,7 +102,7 @@ public sealed class OpenIddictConfiguration
public HashSet<string> TokenEndpointAuthMethodsSupported { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the address of the userinfo endpoint.
/// Gets or sets the URI of the userinfo endpoint.
/// </summary>
public Uri? UserinfoEndpoint { get; set; }
}

26
src/OpenIddict.Abstractions/Stores/IOpenIddictApplicationStore.cs

@ -80,20 +80,20 @@ public interface IOpenIddictApplicationStore<TApplication> where TApplication :
/// <summary>
/// Retrieves all the applications associated with the specified post_logout_redirect_uri.
/// </summary>
/// <param name="address">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="uri">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified post_logout_redirect_uri.</returns>
IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken);
/// <summary>
/// Retrieves all the applications associated with the specified redirect_uri.
/// </summary>
/// <param name="address">The redirect_uri associated with the applications.</param>
/// <param name="uri">The redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified redirect_uri.</returns>
IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken);
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken);
/// <summary>
/// Executes the specified query and returns the first element.
@ -202,7 +202,7 @@ public interface IOpenIddictApplicationStore<TApplication> where TApplication :
ValueTask<ImmutableArray<string>> GetPermissionsAsync(TApplication application, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the logout callback addresses associated with an application.
/// Retrieves the post-logout redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
@ -224,7 +224,7 @@ public interface IOpenIddictApplicationStore<TApplication> where TApplication :
ValueTask<ImmutableDictionary<string, JsonElement>> GetPropertiesAsync(TApplication application, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the callback addresses associated with an application.
/// Retrieves the redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
@ -344,14 +344,13 @@ public interface IOpenIddictApplicationStore<TApplication> where TApplication :
ValueTask SetPermissionsAsync(TApplication application, ImmutableArray<string> permissions, CancellationToken cancellationToken);
/// <summary>
/// Sets the logout callback addresses associated with an application.
/// Sets the post-logout redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="addresses">The logout callback addresses associated with the application </param>
/// <param name="uris">The post-logout redirect URIs associated with the application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.</returns>
ValueTask SetPostLogoutRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken);
ValueTask SetPostLogoutRedirectUrisAsync(TApplication application, ImmutableArray<string> uris, CancellationToken cancellationToken);
/// <summary>
/// Sets the additional properties associated with an application.
@ -364,14 +363,13 @@ public interface IOpenIddictApplicationStore<TApplication> where TApplication :
ImmutableDictionary<string, JsonElement> properties, CancellationToken cancellationToken);
/// <summary>
/// Sets the callback addresses associated with an application.
/// Sets the redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="addresses">The callback addresses associated with the application </param>
/// <param name="uris">The redirect URIs associated with the application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.</returns>
ValueTask SetRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken);
ValueTask SetRedirectUrisAsync(TApplication application, ImmutableArray<string> uris, CancellationToken cancellationToken);
/// <summary>
/// Sets the requirements associated with an application.

4
src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs

@ -172,8 +172,8 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler<Op
properties.ExpiresUtc = principal.GetExpirationDate();
properties.IssuedUtc = principal.GetCreationDate();
// Restore the return URL using the "target_link_uri" that was stored
// in the state token when the challenge operation started, if available.
// Restore the target link URI that was stored in the state
// token when the challenge operation started, if available.
properties.RedirectUri = context.StateTokenPrincipal?.GetClaim(Claims.TargetLinkUri);
List<AuthenticationToken>? tokens = null;

6
src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs

@ -95,7 +95,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers
// sent by the HTTP client) is not desirable as it would affect all requests, including requests
// that are not meant to be handled by OpenIddict itself. To avoid that, a fake host is temporarily
// used to build an absolute base URI and a request URI that will be used to determine whether the
// received request matches one of the addresses assigned to an OpenIddict endpoint. If the request
// received request matches one of the URIs assigned to an OpenIddict endpoint. If the request
// is later handled by OpenIddict, an additional check will be made to require the Host header.
(context.BaseUri, context.RequestUri) = request.Host switch
@ -464,7 +464,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers
context.ProviderName = provider;
}
// If a return URL was specified, use it as the target_link_uri claim.
// If a target link URI was specified, attach it to the context.
if (!string.IsNullOrEmpty(properties.RedirectUri))
{
context.TargetLinkUri = properties.RedirectUri;
@ -697,7 +697,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers
context.ProviderName = provider;
}
// If a return URL was specified, use it as the target_link_uri claim.
// If a target link URI was specified, attach it to the context.
if (!string.IsNullOrEmpty(properties.RedirectUri))
{
context.TargetLinkUri = properties.RedirectUri;

4
src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs

@ -187,8 +187,8 @@ public sealed class OpenIddictClientOwinHandler : AuthenticationHandler<OpenIddi
properties.ExpiresUtc = principal.GetExpirationDate();
properties.IssuedUtc = principal.GetCreationDate();
// Restore the return URL using the "target_link_uri" that was stored
// in the state token when the challenge operation started, if available.
// Restore the target link URI that was stored in the state
// token when the challenge operation started, if available.
properties.RedirectUri = context.StateTokenPrincipal?.GetClaim(Claims.TargetLinkUri);
// Attach the tokens to allow any OWIN component (e.g a controller)

6
src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs

@ -90,7 +90,7 @@ public static partial class OpenIddictClientOwinHandlers
// sent by the HTTP client) is not desirable as it would affect all requests, including requests
// that are not meant to be handled by OpenIddict itself. To avoid that, a fake host is temporarily
// used to build an absolute base URI and a request URI that will be used to determine whether the
// received request matches one of the addresses assigned to an OpenIddict endpoint. If the request
// received request matches one of the URIs assigned to an OpenIddict endpoint. If the request
// is later handled by OpenIddict, an additional check will be made to require the Host header.
(context.BaseUri, context.RequestUri) = request.Host switch
@ -477,7 +477,7 @@ public static partial class OpenIddictClientOwinHandlers
context.ProviderName = provider;
}
// If a return URL was specified, use it as the target_link_uri claim.
// If a target link URI was specified, attach it to the context.
if (!string.IsNullOrEmpty(properties.RedirectUri))
{
context.TargetLinkUri = properties.RedirectUri;
@ -736,7 +736,7 @@ public static partial class OpenIddictClientOwinHandlers
context.ProviderName = provider;
}
// If a return URL was specified, use it as the target_link_uri claim.
// If a target link URI was specified, attach it to the context.
if (!string.IsNullOrEmpty(properties.RedirectUri))
{
context.TargetLinkUri = properties.RedirectUri;

2
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpExtensions.cs

@ -37,7 +37,7 @@ public static class OpenIddictClientSystemNetHttpExtensions
builder.Services.TryAdd(OpenIddictClientSystemNetHttpHandlers.DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));
// Register the built-in filters used by the default OpenIddict System.Net.Http event handlers.
builder.Services.TryAddSingleton<RequireHttpMetadataAddress>();
builder.Services.TryAddSingleton<RequireHttpMetadataUri>();
// Note: TryAddEnumerable() is used here to ensure the initializers are registered only once.
builder.Services.TryAddEnumerable(new[]

8
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlerFilters.cs

@ -12,9 +12,9 @@ namespace OpenIddict.Client.SystemNetHttp;
public static class OpenIddictClientSystemNetHttpHandlerFilters
{
/// <summary>
/// Represents a filter that excludes the associated handlers if the metadata address of the issuer is not available.
/// Represents a filter that excludes the associated handlers if the metadata URI of the issuer is not available.
/// </summary>
public sealed class RequireHttpMetadataAddress : IOpenIddictClientHandlerFilter<BaseExternalContext>
public sealed class RequireHttpMetadataUri : IOpenIddictClientHandlerFilter<BaseExternalContext>
{
public ValueTask<bool> IsActiveAsync(BaseExternalContext context)
{
@ -24,8 +24,8 @@ public static class OpenIddictClientSystemNetHttpHandlerFilters
}
return new(
string.Equals(context.Address?.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
string.Equals(context.Address?.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase));
string.Equals(context.RemoteUri?.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
string.Equals(context.RemoteUri?.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase));
}
}
}

2
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs

@ -46,7 +46,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareTokenRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachBasicAuthenticationCredentials>()
.SetOrder(AttachFormParameters<PrepareTokenRequestContext>.Descriptor.Order - 500)
.SetType(OpenIddictClientHandlerType.BuiltIn)

4
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs

@ -47,7 +47,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareUserinfoRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachBearerAccessToken>()
.SetOrder(AttachQueryStringParameters<PrepareUserinfoRequestContext>.Descriptor.Order - 500)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -88,7 +88,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<ExtractUserinfoResponseContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ExtractUserinfoTokenHttpResponse>()
.SetOrder(ExtractJsonHttpResponse<ExtractUserinfoResponseContext>.Descriptor.Order - 500)
.SetType(OpenIddictClientHandlerType.BuiltIn)

30
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs

@ -36,7 +36,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<PrepareGetHttpRequest<TContext>>()
.SetOrder(int.MinValue + 100_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -52,7 +52,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
// Store the HttpRequestMessage in the transaction properties.
context.Transaction.SetProperty(typeof(HttpRequestMessage).FullName!,
new HttpRequestMessage(HttpMethod.Get, context.Address));
new HttpRequestMessage(HttpMethod.Get, context.RemoteUri));
return default;
}
@ -68,7 +68,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<PreparePostHttpRequest<TContext>>()
.SetOrder(PrepareGetHttpRequest<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -84,7 +84,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
// Store the HttpRequestMessage in the transaction properties.
context.Transaction.SetProperty(typeof(HttpRequestMessage).FullName!,
new HttpRequestMessage(HttpMethod.Post, context.Address));
new HttpRequestMessage(HttpMethod.Post, context.RemoteUri));
return default;
}
@ -101,7 +101,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachJsonAcceptHeaders<TContext>>()
.SetOrder(PreparePostHttpRequest<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -146,7 +146,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachUserAgentHeader<TContext>>()
.SetOrder(AttachJsonAcceptHeaders<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -195,7 +195,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachQueryStringParameters<TContext>>()
.SetOrder(AttachFormParameters<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -240,7 +240,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachFormParameters<TContext>>()
.SetOrder(int.MaxValue - 100_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -287,7 +287,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<SendHttpRequest<TContext>>()
.SetOrder(DecompressResponseContent<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -360,7 +360,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<DisposeHttpRequest<TContext>>()
.SetOrder(int.MaxValue - 100_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -398,7 +398,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<DecompressResponseContent<TContext>>()
.SetOrder(ExtractJsonHttpResponse<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -537,7 +537,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ExtractJsonHttpResponse<TContext>>()
.SetOrder(ExtractWwwAuthenticateHeader<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -605,7 +605,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ExtractWwwAuthenticateHeader<TContext>>()
.SetOrder(ValidateHttpResponse<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -688,7 +688,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ValidateHttpResponse<TContext>>()
.SetOrder(DisposeHttpResponse<TContext>.Descriptor.Order - 50_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -758,7 +758,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<DisposeHttpResponse<TContext>>()
.SetOrder(int.MaxValue - 100_000)
.SetType(OpenIddictClientHandlerType.BuiltIn)

2
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs

@ -38,7 +38,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareTokenRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachNonStandardQueryStringParameters>()
.SetOrder(AttachQueryStringParameters<PrepareTokenRequestContext>.Descriptor.Order + 500)
.SetType(OpenIddictClientHandlerType.BuiltIn)

4
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs

@ -44,7 +44,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareUserinfoRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachRequestHeaders>()
.SetOrder(AttachUserAgentHeader<PrepareUserinfoRequestContext>.Descriptor.Order + 250)
.SetType(OpenIddictClientHandlerType.BuiltIn)
@ -88,7 +88,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
/// </summary>
public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareUserinfoRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachAccessTokenParameter>()
.SetOrder(AttachBearerAccessToken.Descriptor.Order + 250)
.SetType(OpenIddictClientHandlerType.BuiltIn)

4
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs

@ -258,7 +258,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
{
Providers.Deezer or
Providers.Mixcloud => OpenIddictHelpers.AddQueryStringParameter(
address: new Uri(context.TokenRequest.RedirectUri, UriKind.Absolute),
uri: new Uri(context.TokenRequest.RedirectUri, UriKind.Absolute),
name: Parameters.State,
value: context.StateToken).AbsoluteUri,
@ -500,7 +500,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
{
Providers.Deezer or
Providers.Mixcloud => (OpenIddictHelpers.AddQueryStringParameter(
address: new Uri(context.RedirectUri, UriKind.Absolute),
uri: new Uri(context.RedirectUri, UriKind.Absolute),
name: Parameters.State,
value: context.Request.State).AbsoluteUri, null),

6
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

@ -56,14 +56,14 @@
<Provider Name="Keycloak" Documentation="https://www.keycloak.org/getting-started/getting-started-docker">
<!--
Note: Keycloak is a self-hosted-only identity provider that doesn't have a generic issuer address.
As such, the complete address must always be set in the options and include the realm, if applicable.
Note: Keycloak is a self-hosted-only identity provider that doesn't have a generic issuer URI.
As such, the complete URI must always be set in the options and include the realm, if applicable.
-->
<Environment Issuer="{issuer}" />
<Setting PropertyName="Issuer" ParameterName="issuer" Type="Uri" Required="true"
Description="The address used to access the Keycloak identity provider (including the realm, if applicable)" />
Description="The URI used to access the Keycloak identity provider (including the realm, if applicable)" />
</Provider>
<Provider Name="LinkedIn" Documentation="https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin">

4
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xsd

@ -216,7 +216,7 @@
<xs:attribute name="Issuer" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The issuer URL corresponding to the environment.</xs:documentation>
<xs:documentation>The issuer URI corresponding to the environment.</xs:documentation>
</xs:annotation>
</xs:attribute>
@ -421,7 +421,7 @@
<xs:attribute name="Documentation" type="xs:anyURI" use="optional">
<xs:annotation>
<xs:documentation>The documentation URL, if applicable.</xs:documentation>
<xs:documentation>The documentation URI, if applicable.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>

84
src/OpenIddict.Client/OpenIddictClientBuilder.cs

@ -999,108 +999,108 @@ public sealed class OpenIddictClientBuilder
=> Configure(options => options.GrantTypes.Add(GrantTypes.RefreshToken));
/// <summary>
/// Sets the relative or absolute URLs associated to the redirection endpoint.
/// Sets the relative or absolute URIs associated to the redirection endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// </summary>
/// <remarks>
/// Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint
/// address per provider, unless all the registered providers support returning an "iss"
/// parameter containing their URL as part of authorization responses. For more information,
/// URI per provider, unless all the registered providers support returning an "iss" parameter
/// containing their identity as part of authorization responses. For more information,
/// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4.
/// </remarks>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictClientBuilder"/> instance.</returns>
public OpenIddictClientBuilder SetRedirectionEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetRedirectionEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetRedirectionEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the redirection endpoint.
/// Sets the relative or absolute URIs associated to the redirection endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// </summary>
/// <remarks>
/// Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint
/// address per provider, unless all the registered providers support returning an "iss"
/// parameter containing their URL as part of authorization responses. For more information,
/// URI per provider, unless all the registered providers support returning an "iss" parameter
/// containing their identity as part of authorization responses. For more information,
/// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4.
/// </remarks>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictClientBuilder"/> instance.</returns>
public OpenIddictClientBuilder SetRedirectionEndpointUris(params Uri[] addresses)
public OpenIddictClientBuilder SetRedirectionEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (Array.Exists(addresses, static address => !address.IsWellFormedOriginalString()))
if (Array.Exists(uris, static uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (Array.Exists(addresses, static address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (Array.Exists(uris, static uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.RedirectionEndpointUris.Clear();
options.RedirectionEndpointUris.AddRange(addresses);
options.RedirectionEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the post-logout redirection endpoint.
/// Sets the relative or absolute URIs associated to the post-logout redirection endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictClientBuilder"/> instance.</returns>
public OpenIddictClientBuilder SetPostLogoutRedirectionEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetPostLogoutRedirectionEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetPostLogoutRedirectionEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the post-logout redirection endpoint.
/// Sets the relative or absolute URIs associated to the post-logout redirection endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictClientBuilder"/> instance.</returns>
public OpenIddictClientBuilder SetPostLogoutRedirectionEndpointUris(params Uri[] addresses)
public OpenIddictClientBuilder SetPostLogoutRedirectionEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (Array.Exists(addresses, static address => !address.IsWellFormedOriginalString()))
if (Array.Exists(uris, static uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (Array.Exists(addresses, static address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (Array.Exists(uris, static uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.PostLogoutRedirectionEndpointUris.Clear();
options.PostLogoutRedirectionEndpointUris.AddRange(addresses);
options.PostLogoutRedirectionEndpointUris.AddRange(uris);
});
}
@ -1127,19 +1127,19 @@ public sealed class OpenIddictClientBuilder
=> Configure(options => options.StateTokenLifetime = lifetime);
/// <summary>
/// Sets the client URI, which is used as the value for the "issuer" claim.
/// Sets the client URI, which is used as the value of the "issuer" claim.
/// </summary>
/// <param name="address">The client URI.</param>
/// <param name="uri">The client URI.</param>
/// <returns>The <see cref="OpenIddictClientBuilder"/> instance.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictClientBuilder SetClientUri(Uri address)
public OpenIddictClientBuilder SetClientUri(Uri uri)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
return Configure(options => options.ClientUri = address);
return Configure(options => options.ClientUri = uri);
}
/// <inheritdoc/>

12
src/OpenIddict.Client/OpenIddictClientConfiguration.cs

@ -70,12 +70,12 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions<OpenId
throw new InvalidOperationException(SR.GetResourceString(SR.ID0313));
}
registration.MetadataAddress = OpenIddictHelpers.CreateAbsoluteUri(
registration.ConfigurationEndpoint = OpenIddictHelpers.CreateAbsoluteUri(
registration.Issuer,
registration.MetadataAddress ?? new Uri(".well-known/openid-configuration", UriKind.Relative));
registration.ConfigurationEndpoint ?? new Uri(".well-known/openid-configuration", UriKind.Relative));
registration.ConfigurationManager = new ConfigurationManager<OpenIddictConfiguration>(
registration.MetadataAddress.AbsoluteUri, new OpenIddictClientRetriever(_service, registration))
registration.ConfigurationEndpoint.AbsoluteUri, new OpenIddictClientRetriever(_service, registration))
{
AutomaticRefreshInterval = ConfigurationManager<OpenIddictConfiguration>.DefaultAutomaticRefreshInterval,
RefreshInterval = ConfigurationManager<OpenIddictConfiguration>.DefaultRefreshInterval
@ -90,12 +90,12 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions<OpenId
throw new InvalidOperationException(SR.GetResourceString(SR.ID0076));
}
var addresses = options.RedirectionEndpointUris.Distinct()
var uris = options.RedirectionEndpointUris.Distinct()
.Concat(options.PostLogoutRedirectionEndpointUris.Distinct())
.ToList();
// Ensure endpoint addresses are unique across endpoints.
if (addresses.Count != addresses.Distinct().Count())
// Ensure endpoint URIs are unique across endpoints.
if (uris.Count != uris.Distinct().Count())
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0285));
}

14
src/OpenIddict.Client/OpenIddictClientEvents.cs

@ -140,9 +140,9 @@ public static partial class OpenIddictClientEvents
}
/// <summary>
/// Gets or sets the address of the external endpoint to communicate with.
/// Gets or sets the URI of the external endpoint to communicate with.
/// </summary>
public Uri? Address { get; set; }
public Uri? RemoteUri { get; set; }
}
/// <summary>
@ -271,7 +271,7 @@ public static partial class OpenIddictClientEvents
public string? ErrorDescription { get; set; }
/// <summary>
/// Gets or sets the error URL returned to the caller.
/// Gets or sets the error URI returned to the caller.
/// </summary>
public string? ErrorUri { get; set; }
@ -334,12 +334,12 @@ public static partial class OpenIddictClientEvents
public HashSet<string> Scopes { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the address of the token endpoint, if applicable.
/// Gets or sets the URI of the token endpoint, if applicable.
/// </summary>
public Uri? TokenEndpoint { get; set; }
/// <summary>
/// Gets or sets the address of the userinfo endpoint, if applicable.
/// Gets or sets the URI of the userinfo endpoint, if applicable.
/// </summary>
public Uri? UserinfoEndpoint { get; set; }
@ -803,7 +803,7 @@ public static partial class OpenIddictClientEvents
public string? RequestForgeryProtection { get; set; }
/// <summary>
/// Gets or sets the optional return URL that will be stored in the state token, if applicable.
/// Gets or sets the optional target link URI that will be stored in the state token, if applicable.
/// </summary>
[StringSyntax(StringSyntaxAttribute.Uri)]
public string? TargetLinkUri { get; set; }
@ -925,7 +925,7 @@ public static partial class OpenIddictClientEvents
public string? LoginHint { get; set; }
/// <summary>
/// Gets or sets the optional return URL that will be stored in the state token, if applicable.
/// Gets or sets the optional target link URI that will be stored in the state token, if applicable.
/// </summary>
public string? TargetLinkUri { get; set; }

4
src/OpenIddict.Client/OpenIddictClientHandlers.Authentication.cs

@ -135,7 +135,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for attaching the address of the authorization request to the request.
/// Contains the logic responsible for attaching the URI of the authorization request to the request.
/// </summary>
public sealed class AttachAuthorizationEndpoint : IOpenIddictClientHandler<ApplyAuthorizationRequestContext>
{
@ -156,7 +156,7 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
// Ensure the authorization endpoint is present and is a valid absolute URL.
// Ensure the authorization endpoint is present and is a valid absolute URI.
if (context.Configuration.AuthorizationEndpoint is not { IsAbsoluteUri: true } ||
!context.Configuration.AuthorizationEndpoint.IsWellFormedOriginalString())
{

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

@ -201,7 +201,7 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
// Note: the issuer returned in the discovery document must exactly match the URL used to access it.
// Note: the issuer returned in the discovery document must exactly match the URI used to access it.
// See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation.
var issuer = (string?) context.Response[Metadata.Issuer];
@ -215,7 +215,7 @@ public static partial class OpenIddictClientHandlers
return default;
}
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri? address))
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri? uri))
{
context.Reject(
error: Errors.ServerError,
@ -226,7 +226,7 @@ public static partial class OpenIddictClientHandlers
}
// Ensure the issuer matches the expected value.
if (address != context.Registration.Issuer)
if (uri != context.Registration.Issuer)
{
context.Reject(
error: Errors.ServerError,
@ -236,14 +236,14 @@ public static partial class OpenIddictClientHandlers
return default;
}
context.Configuration.Issuer = address;
context.Configuration.Issuer = uri;
return default;
}
}
/// <summary>
/// Contains the logic responsible for extracting the authorization endpoint address from the discovery document.
/// Contains the logic responsible for extracting the authorization endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractAuthorizationEndpoint : IOpenIddictClientHandler<HandleConfigurationResponseContext>
{
@ -269,15 +269,15 @@ public static partial class OpenIddictClientHandlers
// but is optional in the OAuth 2.0 authorization server metadata specification. To make OpenIddict
// compatible with the newer OAuth 2.0 specification, null/empty and missing values are allowed here.
//
// Handlers that require a non-null authorization endpoint URL are expected to return an error
// if the authorization endpoint URL couldn't be resolved from the authorization server metadata.
// Handlers that require a non-null authorization endpoint URI are expected to return an error
// if the authorization endpoint URI couldn't be resolved from the authorization server metadata.
// See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationClient
// and https://datatracker.ietf.org/doc/html/rfc8414#section-2 for more information.
//
var address = (string?) context.Response[Metadata.AuthorizationEndpoint];
if (!string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.AuthorizationEndpoint];
if (!string.IsNullOrEmpty(endpoint))
{
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,
@ -295,7 +295,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for extracting the JWKS endpoint address from the discovery document.
/// Contains the logic responsible for extracting the JWKS endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractCryptographyEndpoint : IOpenIddictClientHandler<HandleConfigurationResponseContext>
{
@ -319,8 +319,8 @@ public static partial class OpenIddictClientHandlers
// Note: the jwks_uri node is required by the OpenID Connect discovery specification.
// See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationClient.
var address = (string?) context.Response[Metadata.JwksUri];
if (string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.JwksUri];
if (string.IsNullOrEmpty(endpoint))
{
context.Reject(
error: Errors.ServerError,
@ -330,7 +330,7 @@ public static partial class OpenIddictClientHandlers
return default;
}
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,
@ -347,7 +347,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for extracting the logout endpoint address from the discovery document.
/// Contains the logic responsible for extracting the logout endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractLogoutEndpoint : IOpenIddictClientHandler<HandleConfigurationResponseContext>
{
@ -369,10 +369,10 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var address = (string?) context.Response[Metadata.EndSessionEndpoint];
if (!string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.EndSessionEndpoint];
if (!string.IsNullOrEmpty(endpoint))
{
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,
@ -390,7 +390,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for extracting the token endpoint address from the discovery document.
/// Contains the logic responsible for extracting the token endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractTokenEndpoint : IOpenIddictClientHandler<HandleConfigurationResponseContext>
{
@ -412,10 +412,10 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var address = (string?) context.Response[Metadata.TokenEndpoint];
if (!string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.TokenEndpoint];
if (!string.IsNullOrEmpty(endpoint))
{
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,
@ -433,7 +433,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for extracting the userinfo endpoint address from the discovery document.
/// Contains the logic responsible for extracting the userinfo endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractUserinfoEndpoint : IOpenIddictClientHandler<HandleConfigurationResponseContext>
{
@ -455,10 +455,10 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
var address = (string?) context.Response[Metadata.UserinfoEndpoint];
if (!string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.UserinfoEndpoint];
if (!string.IsNullOrEmpty(endpoint))
{
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,

19
src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs

@ -83,10 +83,10 @@ public static partial class OpenIddictClientHandlers
{
// When only state tokens are considered valid, use the token validation parameters of the client.
1 when context.ValidTokenTypes.Contains(TokenTypeHints.StateToken)
=> GetClientTokenValidationParameters(context.BaseUri, context.Options),
=> GetClientTokenValidationParameters(),
// Otherwise, use the token validation parameters of the authorization server.
_ => GetServerTokenValidationParameters(context.Registration, context.Configuration)
_ => GetServerTokenValidationParameters()
};
context.SecurityTokenHandler = context.Options.JsonWebTokenHandler;
@ -94,11 +94,11 @@ public static partial class OpenIddictClientHandlers
return default;
static TokenValidationParameters GetClientTokenValidationParameters(Uri? address, OpenIddictClientOptions options)
TokenValidationParameters GetClientTokenValidationParameters()
{
var parameters = options.TokenValidationParameters.Clone();
var parameters = context.Options.TokenValidationParameters.Clone();
parameters.ValidIssuers ??= (options.ClientUri ?? address) switch
parameters.ValidIssuers ??= (context.Options.ClientUri ?? context.BaseUri) switch
{
null => null,
@ -122,12 +122,11 @@ public static partial class OpenIddictClientHandlers
return parameters;
}
static TokenValidationParameters GetServerTokenValidationParameters(
OpenIddictClientRegistration registration, OpenIddictConfiguration configuration)
TokenValidationParameters GetServerTokenValidationParameters()
{
var parameters = registration!.TokenValidationParameters.Clone();
var parameters = context.Registration.TokenValidationParameters.Clone();
parameters.ValidIssuers ??= configuration.Issuer switch
parameters.ValidIssuers ??= context.Configuration.Issuer switch
{
null => null,
@ -148,7 +147,7 @@ public static partial class OpenIddictClientHandlers
// Combine the signing keys registered statically in the token validation parameters
// with the signing keys resolved from the OpenID Connect server configuration.
parameters.IssuerSigningKeys =
parameters.IssuerSigningKeys?.Concat(configuration.SigningKeys) ?? configuration.SigningKeys;
parameters.IssuerSigningKeys?.Concat(context.Configuration.SigningKeys) ?? context.Configuration.SigningKeys;
// For maximum compatibility, all "typ" values are accepted for all types of JSON Web Tokens,
// which typically includes identity tokens but can also include access tokens, authorization

4
src/OpenIddict.Client/OpenIddictClientHandlers.Session.cs

@ -128,7 +128,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for attaching the address of the authorization request to the request.
/// Contains the logic responsible for attaching the URI of the authorization request to the request.
/// </summary>
public sealed class AttachLogoutEndpoint : IOpenIddictClientHandler<ApplyLogoutRequestContext>
{
@ -149,7 +149,7 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
// Ensure the end session endpoint is present and is a valid absolute URL.
// Ensure the end session endpoint is present and is a valid absolute URI.
if (context.Configuration.EndSessionEndpoint is not { IsAbsoluteUri: true } ||
!context.Configuration.EndSessionEndpoint.IsWellFormedOriginalString())
{

62
src/OpenIddict.Client/OpenIddictClientHandlers.cs

@ -142,7 +142,7 @@ public static partial class OpenIddictClientHandlers
.AddRange(Userinfo.DefaultHandlers);
/// <summary>
/// Contains the logic responsible for inferring the endpoint type from the request address.
/// Contains the logic responsible for inferring the endpoint type from the request URI.
/// </summary>
public sealed class InferEndpointType : IOpenIddictClientHandler<ProcessRequestContext>
{
@ -176,14 +176,14 @@ public static partial class OpenIddictClientHandlers
return default;
bool Matches(IReadOnlyList<Uri> addresses)
bool Matches(IReadOnlyList<Uri> candidates)
{
for (var index = 0; index < addresses.Count; index++)
for (var index = 0; index < candidates.Count; index++)
{
var address = addresses[index];
if (address.IsAbsoluteUri)
var candidate = candidates[index];
if (candidate.IsAbsoluteUri)
{
if (Equals(address, context.RequestUri))
if (Equals(candidate, context.RequestUri))
{
return true;
}
@ -191,7 +191,7 @@ public static partial class OpenIddictClientHandlers
else
{
var uri = OpenIddictHelpers.CreateAbsoluteUri(context.BaseUri, address);
var uri = OpenIddictHelpers.CreateAbsoluteUri(context.BaseUri, candidate);
if (uri.IsWellFormedOriginalString() &&
OpenIddictHelpers.IsBaseOf(context.BaseUri, uri) && Equals(uri, context.RequestUri))
{
@ -737,7 +737,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for comparing the current request URL to the expected URL stored in the state token.
/// Contains the logic responsible for comparing the current request URI to the expected URI stored in the state token.
/// </summary>
public sealed class ValidateEndpointUri : IOpenIddictClientHandler<ProcessAuthenticationContext>
{
@ -789,7 +789,7 @@ public static partial class OpenIddictClientHandlers
return default;
}
// Compare the current HTTP request address to the original endpoint URI. If the two don't
// Compare the current HTTP request URI to the original endpoint URI. If the two don't
// match, this may indicate a mix-up attack. While the authorization server is expected to
// abort the authorization flow by rejecting the token request that may be eventually sent
// with the original endpoint URI, many servers are known to incorrectly implement this
@ -800,8 +800,8 @@ public static partial class OpenIddictClientHandlers
//
// See https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-19#section-4.4.2.2
// for more information.
var address = new Uri(value, UriKind.Absolute);
if (new UriBuilder(address) { Query = null }.Uri !=
var uri = new Uri(value, UriKind.Absolute);
if (new UriBuilder(uri) { Query = null }.Uri !=
new UriBuilder(context.RequestUri!) { Query = null }.Uri)
{
context.Reject(
@ -815,11 +815,11 @@ public static partial class OpenIddictClientHandlers
// Ensure all the query string parameters that were part of the original endpoint URI
// are present in the current request (parameters that were not part of the original
// endpoint URI are assumed to be authorization response parameters and are ignored).
if (!string.IsNullOrEmpty(address.Query))
if (!string.IsNullOrEmpty(uri.Query))
{
var parameters = OpenIddictHelpers.ParseQuery(context.RequestUri!.Query);
foreach (var parameter in OpenIddictHelpers.ParseQuery(address.Query))
foreach (var parameter in OpenIddictHelpers.ParseQuery(uri.Query))
{
if (!parameters.TryGetValue(parameter.Key, out StringValues values) ||
!parameter.Value.Equals(values))
@ -1953,7 +1953,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for resolving the address of the token endpoint.
/// Contains the logic responsible for resolving the URI of the token endpoint.
/// </summary>
public sealed class ResolveTokenEndpoint : IOpenIddictClientHandler<ProcessAuthenticationContext>
{
@ -1975,11 +1975,11 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
// If the address of the token endpoint wasn't explicitly set
// at this stage, try to extract it from the server configuration.
// If the URI of the token endpoint wasn't explicitly set at
// this stage, try to extract it from the server configuration.
context.TokenEndpoint ??= context.Configuration.TokenEndpoint switch
{
{ IsAbsoluteUri: true } address when address.IsWellFormedOriginalString() => address,
{ IsAbsoluteUri: true } uri when uri.IsWellFormedOriginalString() => uri,
_ => null
};
@ -2193,7 +2193,7 @@ public static partial class OpenIddictClientHandlers
principal.SetExpirationDate(principal.GetCreationDate() + lifetime.Value);
}
// Use the address of the token endpoint as the audience, as recommended by the specifications.
// Use the URI of the token endpoint as the audience, as recommended by the specifications.
// Applications that need to use a different value can register a custom event handler.
//
// See https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication
@ -2203,7 +2203,7 @@ public static partial class OpenIddictClientHandlers
principal.SetAudiences(context.TokenEndpoint.OriginalString);
}
// If the token endpoint address is not available, use the issuer address as the audience.
// If the token endpoint URI is not available, use the issuer URI as the audience.
else
{
principal.SetAudiences(context.Issuer.OriginalString);
@ -2376,7 +2376,7 @@ public static partial class OpenIddictClientHandlers
Debug.Assert(context.TokenRequest is not null, SR.GetResourceString(SR.ID4008));
// Ensure the token endpoint is present and is a valid absolute URL.
// Ensure the token endpoint is present and is a valid absolute URI.
if (context.TokenEndpoint is not { IsAbsoluteUri: true } ||
!context.TokenEndpoint.IsWellFormedOriginalString())
{
@ -3220,7 +3220,7 @@ public static partial class OpenIddictClientHandlers
}
/// <summary>
/// Contains the logic responsible for resolving the address of the userinfo endpoint.
/// Contains the logic responsible for resolving the URI of the userinfo endpoint.
/// </summary>
public sealed class ResolveUserinfoEndpoint : IOpenIddictClientHandler<ProcessAuthenticationContext>
{
@ -3242,11 +3242,11 @@ public static partial class OpenIddictClientHandlers
throw new ArgumentNullException(nameof(context));
}
// If the address of the userinfo endpoint wasn't explicitly set
// at this stage, try to extract it from the server configuration.
// If the URI of the userinfo endpoint wasn't explicitly set at
// this stage, try to extract it from the server configuration.
context.UserinfoEndpoint ??= context.Configuration.UserinfoEndpoint switch
{
{ IsAbsoluteUri: true } address when address.IsWellFormedOriginalString() => address,
{ IsAbsoluteUri: true } uri when uri.IsWellFormedOriginalString() => uri,
_ => null
};
@ -3362,7 +3362,7 @@ public static partial class OpenIddictClientHandlers
Debug.Assert(context.UserinfoRequest is not null, SR.GetResourceString(SR.ID4008));
// Ensure the userinfo endpoint is present and is a valid absolute URL.
// Ensure the userinfo endpoint is present and is a valid absolute URI.
if (context.UserinfoEndpoint is not { IsAbsoluteUri: true } ||
!context.UserinfoEndpoint.IsWellFormedOriginalString())
{
@ -4127,7 +4127,7 @@ public static partial class OpenIddictClientHandlers
// However, browser-based hosts like Blazor may typically want to use the fragment
// response mode as it offers a better protection for SPA applications.
// Unfortunately, server-side clients like ASP.NET Core applications cannot
// natively use response_mode=fragment as URL fragments are never sent to servers.
// natively use response_mode=fragment as URI fragments are never sent to servers.
//
// As such, this handler will not choose response_mode=fragment by default and it is
// expected that specialized hosts like Blazor implement custom event handlers to
@ -4550,7 +4550,7 @@ public static partial class OpenIddictClientHandlers
// ensure the authorization response sent to the redirection endpoint is not forged.
principal.SetClaim(Claims.RequestForgeryProtection, context.RequestForgeryProtection);
// Store the optional return URL in the state token.
// Store the optional target link URI in the state token.
principal.SetClaim(Claims.TargetLinkUri, context.TargetLinkUri);
// Attach the negotiated grant type to the state token.
@ -4718,7 +4718,7 @@ public static partial class OpenIddictClientHandlers
// Note: while the exact order of the parameters has typically no effect on how requests
// are handled by an authorization server, client_id and redirect_uri are deliberately
// set first so that they appear early in the URL (when GET requests are used), making
// set first so that they appear early in the URI (when GET requests are used), making
// mistyped values easier to spot when an error is returned by the identity provider.
context.Request.ClientId = context.ClientId;
context.Request.RedirectUri = context.RedirectUri;
@ -5160,7 +5160,7 @@ public static partial class OpenIddictClientHandlers
// ensure the logout response sent to the post-logout redirection endpoint is not forged.
principal.SetClaim(Claims.RequestForgeryProtection, context.RequestForgeryProtection);
// Store the optional return URL in the state token.
// Store the optional target link URI in the state token.
principal.SetClaim(Claims.TargetLinkUri, context.TargetLinkUri);
// Store the type of endpoint allowed to receive the generated state token.
@ -5168,7 +5168,7 @@ public static partial class OpenIddictClientHandlers
typeof(OpenIddictClientEndpointType),
OpenIddictClientEndpointType.PostLogoutRedirection)!.ToLowerInvariant());
// Store the post_logout_redirect_uri to allow comparing to the actual redirection URL.
// Store the post_logout_redirect_uri to allow comparing to the actual redirection URI.
principal.SetClaim(Claims.Private.PostLogoutRedirectUri, context.PostLogoutRedirectUri);
// Store the nonce in the state token.
@ -5273,7 +5273,7 @@ public static partial class OpenIddictClientHandlers
// Note: while the exact order of the parameters has typically no effect on how requests
// are handled by an authorization server, client_id and post_logout_redirect_uri are
// set first so that they appear early in the URL (when GET requests are used), making
// set first so that they appear early in the URI (when GET requests are used), making
// mistyped values easier to spot when an error is returned by the identity provider.
context.Request.ClientId = context.ClientId;
context.Request.PostLogoutRedirectUri = context.PostLogoutRedirectUri;

2
src/OpenIddict.Client/OpenIddictClientOptions.cs

@ -16,7 +16,7 @@ namespace OpenIddict.Client;
public sealed class OpenIddictClientOptions
{
/// <summary>
/// Gets or sets the optional address used to uniquely identify the client/relying party.
/// Gets or sets the optional URI used to uniquely identify the client/relying party.
/// The URI must be absolute and may contain a path, but no query string or fragment part.
/// </summary>
public Uri? ClientUri { get; set; }

22
src/OpenIddict.Client/OpenIddictClientRegistration.cs

@ -27,12 +27,12 @@ public sealed class OpenIddictClientRegistration
public string? ClientSecret { get; set; }
/// <summary>
/// Gets or sets the address of the redirection endpoint that will handle the callback.
/// Gets or sets the URI of the redirection endpoint that will handle the callback.
/// </summary>
public Uri? RedirectUri { get; set; }
/// <summary>
/// Gets or sets the address of the post-logout redirection endpoint that will handle the callback.
/// Gets or sets the URI of the post-logout redirection endpoint that will handle the callback.
/// </summary>
public Uri? PostLogoutRedirectUri { get; set; }
@ -91,7 +91,7 @@ public sealed class OpenIddictClientRegistration
public HashSet<string> ResponseModes { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the address of the authorization server.
/// Gets or sets the URI of the authorization server.
/// </summary>
public Uri? Issuer { get; set; }
@ -120,14 +120,10 @@ public sealed class OpenIddictClientRegistration
public IConfigurationManager<OpenIddictConfiguration> ConfigurationManager { get; set; } = default!;
/// <summary>
/// Gets or sets the address of the authorization endpoint exposed by the server.
/// Gets or sets the URI of the configuration endpoint exposed by the server.
/// When the URI is relative, <see cref="Issuer"/> must be set and absolute.
/// </summary>
public Uri? AuthorizationEndpoint { get; set; }
/// <summary>
/// Gets or sets the address of the token endpoint exposed by the server.
/// </summary>
public Uri? TokenEndpoint { get; set; }
public Uri? ConfigurationEndpoint { get; set; }
/// <summary>
/// Gets or sets the token validation parameters associated with the authorization server.
@ -143,12 +139,6 @@ public sealed class OpenIddictClientRegistration
ValidateLifetime = false
};
/// <summary>
/// Gets or sets the URL of the OAuth 2.0/OpenID Connect server discovery endpoint.
/// When the URL is relative, <see cref="Issuer"/> must be set and absolute.
/// </summary>
public Uri? MetadataAddress { get; set; }
/// <summary>
/// Gets the list of scopes sent by default as part of authorization requests.
/// </summary>

2
src/OpenIddict.Client/OpenIddictClientRetriever.cs

@ -29,7 +29,7 @@ public sealed class OpenIddictClientRetriever : IConfigurationRetriever<OpenIddi
}
/// <summary>
/// Retrieves the OpenID Connect server configuration from the specified address.
/// Retrieves the OpenID Connect server configuration from the specified URI.
/// </summary>
/// <param name="address">The address of the remote metadata endpoint.</param>
/// <param name="retriever">The retriever used by IdentityModel.</param>

112
src/OpenIddict.Client/OpenIddictClientService.cs

@ -106,7 +106,7 @@ public sealed class OpenIddictClientService
var configuration = await registration.ConfigurationManager.GetConfigurationAsync(default) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0140));
if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } address || !address.IsWellFormedOriginalString())
if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } uri || !uri.IsWellFormedOriginalString())
{
throw new InvalidOperationException(SR.FormatID0301(Metadata.TokenEndpoint));
}
@ -132,7 +132,7 @@ public sealed class OpenIddictClientService
GrantType = GrantTypes.ClientCredentials,
Issuer = registration.Issuer,
Registration = registration,
TokenEndpoint = address,
TokenEndpoint = uri,
TokenRequest = parameters is not null ? new(parameters) : null,
};
@ -277,7 +277,7 @@ public sealed class OpenIddictClientService
var configuration = await registration.ConfigurationManager.GetConfigurationAsync(default) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0140));
if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } address || !address.IsWellFormedOriginalString())
if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } uri || !uri.IsWellFormedOriginalString())
{
throw new InvalidOperationException(SR.FormatID0301(Metadata.TokenEndpoint));
}
@ -304,7 +304,7 @@ public sealed class OpenIddictClientService
Issuer = registration.Issuer,
Password = password,
Registration = registration,
TokenEndpoint = address,
TokenEndpoint = uri,
TokenRequest = parameters is not null ? new(parameters) : null,
Username = username
};
@ -442,7 +442,7 @@ public sealed class OpenIddictClientService
var configuration = await registration.ConfigurationManager.GetConfigurationAsync(default) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0140));
if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } address || !address.IsWellFormedOriginalString())
if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } uri || !uri.IsWellFormedOriginalString())
{
throw new InvalidOperationException(SR.FormatID0301(Metadata.TokenEndpoint));
}
@ -469,7 +469,7 @@ public sealed class OpenIddictClientService
Issuer = registration.Issuer,
RefreshToken = token,
Registration = registration,
TokenEndpoint = address,
TokenEndpoint = uri,
TokenRequest = parameters is not null ? new(parameters) : null,
};
@ -519,28 +519,28 @@ public sealed class OpenIddictClientService
}
/// <summary>
/// Retrieves the OpenID Connect server configuration from the specified address.
/// Retrieves the OpenID Connect server configuration from the specified uri.
/// </summary>
/// <param name="registration">The client registration.</param>
/// <param name="address">The address of the remote metadata endpoint.</param>
/// <param name="uri">The uri of the remote metadata endpoint.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The OpenID Connect server configuration retrieved from the remote server.</returns>
internal async ValueTask<OpenIddictConfiguration> GetConfigurationAsync(
OpenIddictClientRegistration registration, Uri address, CancellationToken cancellationToken = default)
OpenIddictClientRegistration registration, Uri uri, CancellationToken cancellationToken = default)
{
if (registration is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri || !address.IsWellFormedOriginalString())
if (!uri.IsAbsoluteUri || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
cancellationToken.ThrowIfCancellationRequested();
@ -570,7 +570,7 @@ public sealed class OpenIddictClientService
{
var context = new PrepareConfigurationRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request
};
@ -591,7 +591,7 @@ public sealed class OpenIddictClientService
{
var context = new ApplyConfigurationRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request
};
@ -605,7 +605,7 @@ public sealed class OpenIddictClientService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6186), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6186), context.RemoteUri, context.Request);
return context.Request;
}
@ -614,7 +614,7 @@ public sealed class OpenIddictClientService
{
var context = new ExtractConfigurationResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request
};
@ -630,7 +630,7 @@ public sealed class OpenIddictClientService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6187), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6187), context.RemoteUri, context.Response);
return context.Response;
}
@ -639,7 +639,7 @@ public sealed class OpenIddictClientService
{
var context = new HandleConfigurationResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request,
Response = response
@ -676,25 +676,25 @@ public sealed class OpenIddictClientService
/// Retrieves the security keys exposed by the specified JWKS endpoint.
/// </summary>
/// <param name="registration">The client registration.</param>
/// <param name="address">The address of the remote metadata endpoint.</param>
/// <param name="uri">The uri of the remote metadata endpoint.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The security keys retrieved from the remote server.</returns>
internal async ValueTask<JsonWebKeySet> GetSecurityKeysAsync(
OpenIddictClientRegistration registration, Uri address, CancellationToken cancellationToken = default)
OpenIddictClientRegistration registration, Uri uri, CancellationToken cancellationToken = default)
{
if (registration is null)
{
throw new ArgumentNullException(nameof(registration));
}
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri || !address.IsWellFormedOriginalString())
if (!uri.IsAbsoluteUri || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
cancellationToken.ThrowIfCancellationRequested();
@ -725,7 +725,7 @@ public sealed class OpenIddictClientService
{
var context = new PrepareCryptographyRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request
};
@ -746,7 +746,7 @@ public sealed class OpenIddictClientService
{
var context = new ApplyCryptographyRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request
};
@ -760,7 +760,7 @@ public sealed class OpenIddictClientService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6188), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6188), context.RemoteUri, context.Request);
return context.Request;
}
@ -769,7 +769,7 @@ public sealed class OpenIddictClientService
{
var context = new ExtractCryptographyResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request
};
@ -785,7 +785,7 @@ public sealed class OpenIddictClientService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6189), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6189), context.RemoteUri, context.Response);
return context.Response;
}
@ -794,7 +794,7 @@ public sealed class OpenIddictClientService
{
var context = new HandleCryptographyResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Registration = registration,
Request = request,
Response = response
@ -832,12 +832,12 @@ public sealed class OpenIddictClientService
/// </summary>
/// <param name="registration">The client registration.</param>
/// <param name="request">The token request.</param>
/// <param name="address">The address of the remote token endpoint.</param>
/// <param name="uri">The uri of the remote token endpoint.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The token response.</returns>
internal async ValueTask<OpenIddictResponse> SendTokenRequestAsync(
OpenIddictClientRegistration registration, OpenIddictRequest request,
Uri? address = null, CancellationToken cancellationToken = default)
Uri? uri = null, CancellationToken cancellationToken = default)
{
if (registration is null)
{
@ -849,14 +849,14 @@ public sealed class OpenIddictClientService
throw new ArgumentNullException(nameof(request));
}
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri || !address.IsWellFormedOriginalString())
if (!uri.IsAbsoluteUri || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
var configuration = await registration.ConfigurationManager.GetConfigurationAsync(default) ??
@ -888,7 +888,7 @@ public sealed class OpenIddictClientService
{
var context = new PrepareTokenRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request
@ -910,7 +910,7 @@ public sealed class OpenIddictClientService
{
var context = new ApplyTokenRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request
@ -925,7 +925,7 @@ public sealed class OpenIddictClientService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6192), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6192), context.RemoteUri, context.Request);
return context.Request;
}
@ -934,7 +934,7 @@ public sealed class OpenIddictClientService
{
var context = new ExtractTokenResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request
@ -951,7 +951,7 @@ public sealed class OpenIddictClientService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6193), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6193), context.RemoteUri, context.Response);
return context.Response;
}
@ -960,7 +960,7 @@ public sealed class OpenIddictClientService
{
var context = new HandleTokenResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request,
@ -999,25 +999,25 @@ public sealed class OpenIddictClientService
/// </summary>
/// <param name="registration">The client registration.</param>
/// <param name="request">The userinfo request.</param>
/// <param name="address">The address of the remote userinfo endpoint.</param>
/// <param name="uri">The uri of the remote userinfo endpoint.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The response and the principal extracted from the userinfo response or the userinfo token.</returns>
internal async ValueTask<(OpenIddictResponse Response, (ClaimsPrincipal? Principal, string? Token))> SendUserinfoRequestAsync(
OpenIddictClientRegistration registration, OpenIddictRequest request, Uri address, CancellationToken cancellationToken = default)
OpenIddictClientRegistration registration, OpenIddictRequest request, Uri uri, CancellationToken cancellationToken = default)
{
if (registration is null)
{
throw new ArgumentNullException(nameof(registration));
}
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri || !address.IsWellFormedOriginalString())
if (!uri.IsAbsoluteUri || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
var configuration = await registration.ConfigurationManager.GetConfigurationAsync(default) ??
@ -1049,7 +1049,7 @@ public sealed class OpenIddictClientService
{
var context = new PrepareUserinfoRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request
@ -1071,7 +1071,7 @@ public sealed class OpenIddictClientService
{
var context = new ApplyUserinfoRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request
@ -1086,7 +1086,7 @@ public sealed class OpenIddictClientService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6194), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6194), context.RemoteUri, context.Request);
return context.Request;
}
@ -1095,7 +1095,7 @@ public sealed class OpenIddictClientService
{
var context = new ExtractUserinfoResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request
@ -1112,7 +1112,7 @@ public sealed class OpenIddictClientService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6195), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6195), context.RemoteUri, context.Response);
return (context.Response, context.UserinfoToken);
}
@ -1121,7 +1121,7 @@ public sealed class OpenIddictClientService
{
var context = new HandleUserinfoResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
Request = request,

28
src/OpenIddict.Core/Caches/OpenIddictApplicationCache.cs

@ -57,21 +57,21 @@ public sealed class OpenIddictApplicationCache<TApplication> : IOpenIddictApplic
Identifier = await _store.GetIdAsync(application, cancellationToken)
});
foreach (var address in await _store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
foreach (var uri in await _store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
{
_cache.Remove(new
{
Method = nameof(FindByPostLogoutRedirectUriAsync),
Address = address
Uri = uri
});
}
foreach (var address in await _store.GetRedirectUrisAsync(application, cancellationToken))
foreach (var uri in await _store.GetRedirectUrisAsync(application, cancellationToken))
{
_cache.Remove(new
{
Method = nameof(FindByRedirectUriAsync),
Address = address
Uri = uri
});
}
@ -169,11 +169,11 @@ public sealed class OpenIddictApplicationCache<TApplication> : IOpenIddictApplic
/// <inheritdoc/>
public IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
return ExecuteAsync(cancellationToken);
@ -183,14 +183,14 @@ public sealed class OpenIddictApplicationCache<TApplication> : IOpenIddictApplic
var parameters = new
{
Method = nameof(FindByPostLogoutRedirectUriAsync),
Address = address
Uri = uri
};
if (!_cache.TryGetValue(parameters, out ImmutableArray<TApplication> applications))
{
var builder = ImmutableArray.CreateBuilder<TApplication>();
await foreach (var application in _store.FindByPostLogoutRedirectUriAsync(address, cancellationToken))
await foreach (var application in _store.FindByPostLogoutRedirectUriAsync(uri, cancellationToken))
{
builder.Add(application);
@ -211,11 +211,11 @@ public sealed class OpenIddictApplicationCache<TApplication> : IOpenIddictApplic
/// <inheritdoc/>
public IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
return ExecuteAsync(cancellationToken);
@ -225,14 +225,14 @@ public sealed class OpenIddictApplicationCache<TApplication> : IOpenIddictApplic
var parameters = new
{
Method = nameof(FindByRedirectUriAsync),
Address = address
Uri = uri
};
if (!_cache.TryGetValue(parameters, out ImmutableArray<TApplication> applications))
{
var builder = ImmutableArray.CreateBuilder<TApplication>();
await foreach (var application in _store.FindByRedirectUriAsync(address, cancellationToken))
await foreach (var application in _store.FindByRedirectUriAsync(uri, cancellationToken))
{
builder.Add(application);

130
src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs

@ -326,20 +326,20 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
/// <summary>
/// Retrieves all the applications associated with the specified post_logout_redirect_uri.
/// </summary>
/// <param name="address">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="uri">The post_logout_redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified post_logout_redirect_uri.</returns>
public virtual IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
var applications = Options.CurrentValue.DisableEntityCaching ?
Store.FindByPostLogoutRedirectUriAsync(address, cancellationToken) :
Cache.FindByPostLogoutRedirectUriAsync(address, cancellationToken);
Store.FindByPostLogoutRedirectUriAsync(uri, cancellationToken) :
Cache.FindByPostLogoutRedirectUriAsync(uri, cancellationToken);
if (Options.CurrentValue.DisableAdditionalFiltering)
{
@ -356,8 +356,8 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
{
await foreach (var application in applications)
{
var addresses = await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken);
if (addresses.Contains(address, StringComparer.Ordinal))
var uris = await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken);
if (uris.Contains(uri, StringComparer.Ordinal))
{
yield return application;
}
@ -368,20 +368,20 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
/// <summary>
/// Retrieves all the applications associated with the specified redirect_uri.
/// </summary>
/// <param name="address">The redirect_uri associated with the applications.</param>
/// <param name="uri">The redirect_uri associated with the applications.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The client applications corresponding to the specified redirect_uri.</returns>
public virtual IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
var applications = Options.CurrentValue.DisableEntityCaching ?
Store.FindByRedirectUriAsync(address, cancellationToken) :
Cache.FindByRedirectUriAsync(address, cancellationToken);
Store.FindByRedirectUriAsync(uri, cancellationToken) :
Cache.FindByRedirectUriAsync(uri, cancellationToken);
if (Options.CurrentValue.DisableAdditionalFiltering)
{
@ -398,8 +398,8 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
{
await foreach (var application in applications)
{
var addresses = await Store.GetRedirectUrisAsync(application, cancellationToken);
if (addresses.Contains(address, StringComparer.Ordinal))
var uris = await Store.GetRedirectUrisAsync(application, cancellationToken);
if (uris.Contains(uri, StringComparer.Ordinal))
{
yield return application;
}
@ -665,7 +665,7 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
}
/// <summary>
/// Retrieves the logout callback addresses associated with an application.
/// Retrieves the post-logout redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
@ -705,7 +705,7 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
}
/// <summary>
/// Retrieves the callback addresses associated with an application.
/// Retrieves the redirect URIs associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
@ -916,10 +916,10 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
await Store.SetDisplayNamesAsync(application, descriptor.DisplayNames.ToImmutableDictionary(), cancellationToken);
await Store.SetPermissionsAsync(application, descriptor.Permissions.ToImmutableArray(), cancellationToken);
await Store.SetPostLogoutRedirectUrisAsync(application, ImmutableArray.CreateRange(
descriptor.PostLogoutRedirectUris.Select(address => address.OriginalString)), cancellationToken);
descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString)), cancellationToken);
await Store.SetPropertiesAsync(application, descriptor.Properties.ToImmutableDictionary(), cancellationToken);
await Store.SetRedirectUrisAsync(application, ImmutableArray.CreateRange(
descriptor.RedirectUris.Select(address => address.OriginalString)), cancellationToken);
descriptor.RedirectUris.Select(uri => uri.OriginalString)), cancellationToken);
await Store.SetRequirementsAsync(application, descriptor.Requirements.ToImmutableArray(), cancellationToken);
}
@ -963,21 +963,21 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
}
descriptor.PostLogoutRedirectUris.Clear();
foreach (var address in await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
foreach (var uri in await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
{
// Ensure the address is not null or empty.
if (string.IsNullOrEmpty(address))
// Ensure the URI is not null or empty.
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0213));
}
// Ensure the address is a valid absolute URL.
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
// Ensure the URI is a valid absolute URI.
if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? value) || !value.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0214));
}
descriptor.PostLogoutRedirectUris.Add(uri);
descriptor.PostLogoutRedirectUris.Add(value);
}
descriptor.Properties.Clear();
@ -987,21 +987,21 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
}
descriptor.RedirectUris.Clear();
foreach (var address in await Store.GetRedirectUrisAsync(application, cancellationToken))
foreach (var uri in await Store.GetRedirectUrisAsync(application, cancellationToken))
{
// Ensure the address is not null or empty.
if (string.IsNullOrEmpty(address))
// Ensure the URI is not null or empty.
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0213));
}
// Ensure the address is a valid absolute URL.
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
// Ensure the URI is a valid absolute URI.
if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? value) || !value.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0214));
}
descriptor.RedirectUris.Add(uri);
descriptor.RedirectUris.Add(value);
}
}
@ -1192,30 +1192,30 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
}
}
// When callback URLs are specified, ensure they are valid and spec-compliant.
// When callback URIs are specified, ensure they are valid and spec-compliant.
// See https://tools.ietf.org/html/rfc6749#section-3.1 for more information.
foreach (var address in ImmutableArray.Create<string>()
foreach (var uri in ImmutableArray.Create<string>()
.AddRange(await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
.AddRange(await Store.GetRedirectUrisAsync(application, cancellationToken)))
{
// Ensure the address is not null or empty.
if (string.IsNullOrEmpty(address))
// Ensure the URI is not null or empty.
if (string.IsNullOrEmpty(uri))
{
yield return new ValidationResult(SR.GetResourceString(SR.ID2061));
break;
}
// Ensure the address is a valid absolute URL.
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
// Ensure the URI is a valid absolute URI.
if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? value) || !value.IsWellFormedOriginalString())
{
yield return new ValidationResult(SR.GetResourceString(SR.ID2062));
break;
}
// Ensure the address doesn't contain a fragment.
if (!string.IsNullOrEmpty(uri.Fragment))
// Ensure the URI doesn't contain a fragment.
if (!string.IsNullOrEmpty(value.Fragment))
{
yield return new ValidationResult(SR.GetResourceString(SR.ID2115));
@ -1223,10 +1223,10 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
}
// To prevent issuer fixation attacks where a malicious client would specify an "iss" parameter
// in the callback URL, ensure the query - if present - doesn't include an "iss" parameter.
if (!string.IsNullOrEmpty(uri.Query))
// in the callback URI, ensure the query - if present - doesn't include an "iss" parameter.
if (!string.IsNullOrEmpty(value.Query))
{
var parameters = OpenIddictHelpers.ParseQuery(uri.Query);
var parameters = OpenIddictHelpers.ParseQuery(value.Query);
if (parameters.ContainsKey(Parameters.Iss))
{
yield return new ValidationResult(SR.FormatID2134(Parameters.Iss));
@ -1289,7 +1289,7 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
/// Validates the post_logout_redirect_uri to ensure it's associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="address">The address that should be compared to one of the post_logout_redirect_uri stored in the database.</param>
/// <param name="uri">The URI that should be compared to one of the post_logout_redirect_uri stored in the database.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <remarks>Note: if no client_id parameter is specified in logout requests, this method may not be called.</remarks>
/// <returns>
@ -1297,28 +1297,28 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
/// whose result returns a boolean indicating whether the post_logout_redirect_uri was valid.
/// </returns>
public virtual async ValueTask<bool> ValidatePostLogoutRedirectUriAsync(TApplication application,
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
foreach (var uri in await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
foreach (var candidate in await Store.GetPostLogoutRedirectUrisAsync(application, cancellationToken))
{
// Note: the post_logout_redirect_uri must be compared using case-sensitive "Simple String Comparison".
if (string.Equals(uri, address, StringComparison.Ordinal))
if (string.Equals(candidate, uri, StringComparison.Ordinal))
{
return true;
}
}
Logger.LogInformation(SR.GetResourceString(SR.ID6202), address, await GetClientIdAsync(application, cancellationToken));
Logger.LogInformation(SR.GetResourceString(SR.ID6202), uri, await GetClientIdAsync(application, cancellationToken));
return false;
}
@ -1327,36 +1327,36 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
/// Validates the redirect_uri to ensure it's associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="address">The address that should be compared to one of the redirect_uri stored in the database.</param>
/// <param name="uri">The URI that should be compared to one of the redirect_uri stored in the database.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation,
/// whose result returns a boolean indicating whether the redirect_uri was valid.
/// </returns>
public virtual async ValueTask<bool> ValidateRedirectUriAsync(TApplication application,
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken = default)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken = default)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
foreach (var uri in await Store.GetRedirectUrisAsync(application, cancellationToken))
foreach (var candidate in await Store.GetRedirectUrisAsync(application, cancellationToken))
{
// Note: the redirect_uri must be compared using case-sensitive "Simple String Comparison".
// See http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest for more information.
if (string.Equals(uri, address, StringComparison.Ordinal))
if (string.Equals(candidate, uri, StringComparison.Ordinal))
{
return true;
}
}
Logger.LogInformation(SR.GetResourceString(SR.ID6162), address, await GetClientIdAsync(application, cancellationToken));
Logger.LogInformation(SR.GetResourceString(SR.ID6162), uri, await GetClientIdAsync(application, cancellationToken));
return false;
}
@ -1567,12 +1567,12 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
=> await FindByIdAsync(identifier, cancellationToken);
/// <inheritdoc/>
IAsyncEnumerable<object> IOpenIddictApplicationManager.FindByPostLogoutRedirectUriAsync([StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
=> FindByPostLogoutRedirectUriAsync(address, cancellationToken);
IAsyncEnumerable<object> IOpenIddictApplicationManager.FindByPostLogoutRedirectUriAsync([StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
=> FindByPostLogoutRedirectUriAsync(uri, cancellationToken);
/// <inheritdoc/>
IAsyncEnumerable<object> IOpenIddictApplicationManager.FindByRedirectUriAsync([StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
=> FindByRedirectUriAsync(address, cancellationToken);
IAsyncEnumerable<object> IOpenIddictApplicationManager.FindByRedirectUriAsync([StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
=> FindByRedirectUriAsync(uri, cancellationToken);
/// <inheritdoc/>
ValueTask<TResult?> IOpenIddictApplicationManager.GetAsync<TResult>(Func<IQueryable<object>, IQueryable<TResult>> query, CancellationToken cancellationToken) where TResult : default
@ -1691,10 +1691,10 @@ public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplication
=> ValidateClientSecretAsync((TApplication) application, secret, cancellationToken);
/// <inheritdoc/>
ValueTask<bool> IOpenIddictApplicationManager.ValidatePostLogoutRedirectUriAsync(object application, [StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
=> ValidatePostLogoutRedirectUriAsync((TApplication) application, address, cancellationToken);
ValueTask<bool> IOpenIddictApplicationManager.ValidatePostLogoutRedirectUriAsync(object application, [StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
=> ValidatePostLogoutRedirectUriAsync((TApplication) application, uri, cancellationToken);
/// <inheritdoc/>
ValueTask<bool> IOpenIddictApplicationManager.ValidateRedirectUriAsync(object application, [StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
=> ValidateRedirectUriAsync((TApplication) application, address, cancellationToken);
ValueTask<bool> IOpenIddictApplicationManager.ValidateRedirectUriAsync(object application, [StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
=> ValidateRedirectUriAsync((TApplication) application, uri, cancellationToken);
}

4
src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkApplication.cs

@ -83,7 +83,7 @@ public class OpenIddictEntityFrameworkApplication<TKey, TAuthorization, TToken>
public virtual string? Permissions { get; set; }
/// <summary>
/// Gets or sets the logout callback URLs associated with
/// Gets or sets the post-logout redirect URIs associated with
/// the current application, serialized as a JSON array.
/// </summary>
[StringSyntax(StringSyntaxAttribute.Json)]
@ -97,7 +97,7 @@ public class OpenIddictEntityFrameworkApplication<TKey, TAuthorization, TToken>
public virtual string? Properties { get; set; }
/// <summary>
/// Gets or sets the callback URLs associated with the
/// Gets or sets the redirect URIs associated with the
/// current application, serialized as a JSON array.
/// </summary>
[StringSyntax(StringSyntaxAttribute.Json)]

56
src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs

@ -237,15 +237,15 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
/// <inheritdoc/>
public virtual IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
// To optimize the efficiency of the query a bit, only applications whose stringified
// PostLogoutRedirectUris contains the specified URL are returned. Once the applications
// PostLogoutRedirectUris contains the specified URI are returned. Once the applications
// are retrieved, a second pass is made to ensure only valid elements are returned.
// Implementers that use this method in a hot path may want to override this method
// to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
@ -255,13 +255,13 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
async IAsyncEnumerable<TApplication> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var applications = (from application in Applications
where application.PostLogoutRedirectUris!.Contains(address)
where application.PostLogoutRedirectUris!.Contains(uri)
select application).AsAsyncEnumerable(cancellationToken);
await foreach (var application in applications)
{
var addresses = await GetPostLogoutRedirectUrisAsync(application, cancellationToken);
if (addresses.Contains(address, StringComparer.Ordinal))
var uris = await GetPostLogoutRedirectUrisAsync(application, cancellationToken);
if (uris.Contains(uri, StringComparer.Ordinal))
{
yield return application;
}
@ -271,15 +271,15 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
/// <inheritdoc/>
public virtual IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
// To optimize the efficiency of the query a bit, only applications whose stringified
// RedirectUris property contains the specified URL are returned. Once the applications
// RedirectUris property contains the specified URI are returned. Once the applications
// are retrieved, a second pass is made to ensure only valid elements are returned.
// Implementers that use this method in a hot path may want to override this method
// to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
@ -289,13 +289,13 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
async IAsyncEnumerable<TApplication> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var applications = (from application in Applications
where application.RedirectUris!.Contains(address)
where application.RedirectUris!.Contains(uri)
select application).AsAsyncEnumerable(cancellationToken);
await foreach (var application in applications)
{
var addresses = await GetRedirectUrisAsync(application, cancellationToken);
if (addresses.Contains(address, StringComparer.Ordinal))
var uris = await GetRedirectUrisAsync(application, cancellationToken);
if (uris.Contains(uri, StringComparer.Ordinal))
{
yield return application;
}
@ -477,10 +477,10 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
return new(ImmutableArray.Create<string>());
}
// Note: parsing the stringified addresses is an expensive operation.
// Note: parsing the stringified URIs is an expensive operation.
// To mitigate that, the resulting array is stored in the memory cache.
var key = string.Concat("fb14dfb9-9216-4b77-bfa9-7e85f8201ff4", "\x1e", application.PostLogoutRedirectUris);
var addresses = Cache.GetOrCreate(key, entry =>
var uris = Cache.GetOrCreate(key, entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
@ -502,7 +502,7 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
return builder.ToImmutable();
});
return new(addresses);
return new(uris);
}
/// <inheritdoc/>
@ -553,10 +553,10 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
return new(ImmutableArray.Create<string>());
}
// Note: parsing the stringified addresses is an expensive operation.
// Note: parsing the stringified URIs is an expensive operation.
// To mitigate that, the resulting array is stored in the memory cache.
var key = string.Concat("851d6f08-2ee0-4452-bbe5-ab864611ecaa", "\x1e", application.RedirectUris);
var addresses = Cache.GetOrCreate(key, entry =>
var uris = Cache.GetOrCreate(key, entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
@ -578,7 +578,7 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
return builder.ToImmutable();
});
return new(addresses);
return new(uris);
}
/// <inheritdoc/>
@ -812,14 +812,14 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
/// <inheritdoc/>
public virtual ValueTask SetPostLogoutRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> uris, CancellationToken cancellationToken)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (addresses.IsDefaultOrEmpty)
if (uris.IsDefaultOrEmpty)
{
application.PostLogoutRedirectUris = null;
@ -835,9 +835,9 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
writer.WriteStartArray();
foreach (var address in addresses)
foreach (var uri in uris)
{
writer.WriteStringValue(address);
writer.WriteStringValue(uri);
}
writer.WriteEndArray();
@ -889,14 +889,14 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
/// <inheritdoc/>
public virtual ValueTask SetRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> uris, CancellationToken cancellationToken)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (addresses.IsDefaultOrEmpty)
if (uris.IsDefaultOrEmpty)
{
application.RedirectUris = null;
@ -912,9 +912,9 @@ public class OpenIddictEntityFrameworkApplicationStore<TApplication, TAuthorizat
writer.WriteStartArray();
foreach (var address in addresses)
foreach (var uri in uris)
{
writer.WriteStringValue(address);
writer.WriteStringValue(uri);
}
writer.WriteEndArray();

4
src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreApplication.cs

@ -91,7 +91,7 @@ public class OpenIddictEntityFrameworkCoreApplication<TKey, TAuthorization, TTok
public virtual string? Permissions { get; set; }
/// <summary>
/// Gets or sets the logout callback URLs associated with
/// Gets or sets the post-logout redirect URIs associated with
/// the current application, serialized as a JSON array.
/// </summary>
[StringSyntax(StringSyntaxAttribute.Json)]
@ -105,7 +105,7 @@ public class OpenIddictEntityFrameworkCoreApplication<TKey, TAuthorization, TTok
public virtual string? Properties { get; set; }
/// <summary>
/// Gets or sets the callback URLs associated with the
/// Gets or sets the redirect URIs associated with the
/// current application, serialized as a JSON array.
/// </summary>
[StringSyntax(StringSyntaxAttribute.Json)]

56
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs

@ -279,15 +279,15 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
/// <inheritdoc/>
public virtual IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
// To optimize the efficiency of the query a bit, only applications whose stringified
// PostLogoutRedirectUris contains the specified URL are returned. Once the applications
// PostLogoutRedirectUris contains the specified URI are returned. Once the applications
// are retrieved, a second pass is made to ensure only valid elements are returned.
// Implementers that use this method in a hot path may want to override this method
// to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
@ -297,13 +297,13 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
async IAsyncEnumerable<TApplication> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var applications = (from application in Applications.AsTracking()
where application.PostLogoutRedirectUris!.Contains(address)
where application.PostLogoutRedirectUris!.Contains(uri)
select application).AsAsyncEnumerable(cancellationToken);
await foreach (var application in applications)
{
var addresses = await GetPostLogoutRedirectUrisAsync(application, cancellationToken);
if (addresses.Contains(address, StringComparer.Ordinal))
var uris = await GetPostLogoutRedirectUrisAsync(application, cancellationToken);
if (uris.Contains(uri, StringComparer.Ordinal))
{
yield return application;
}
@ -313,15 +313,15 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
/// <inheritdoc/>
public virtual IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
// To optimize the efficiency of the query a bit, only applications whose stringified
// RedirectUris property contains the specified URL are returned. Once the applications
// RedirectUris property contains the specified URI are returned. Once the applications
// are retrieved, a second pass is made to ensure only valid elements are returned.
// Implementers that use this method in a hot path may want to override this method
// to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
@ -331,13 +331,13 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
async IAsyncEnumerable<TApplication> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var applications = (from application in Applications.AsTracking()
where application.RedirectUris!.Contains(address)
where application.RedirectUris!.Contains(uri)
select application).AsAsyncEnumerable(cancellationToken);
await foreach (var application in applications)
{
var addresses = await GetRedirectUrisAsync(application, cancellationToken);
if (addresses.Contains(address, StringComparer.Ordinal))
var uris = await GetRedirectUrisAsync(application, cancellationToken);
if (uris.Contains(uri, StringComparer.Ordinal))
{
yield return application;
}
@ -519,10 +519,10 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
return new(ImmutableArray.Create<string>());
}
// Note: parsing the stringified addresses is an expensive operation.
// Note: parsing the stringified URIs is an expensive operation.
// To mitigate that, the resulting array is stored in the memory cache.
var key = string.Concat("fb14dfb9-9216-4b77-bfa9-7e85f8201ff4", "\x1e", application.PostLogoutRedirectUris);
var addresses = Cache.GetOrCreate(key, entry =>
var uris = Cache.GetOrCreate(key, entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
@ -544,7 +544,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
return builder.ToImmutable();
});
return new(addresses);
return new(uris);
}
/// <inheritdoc/>
@ -595,10 +595,10 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
return new(ImmutableArray.Create<string>());
}
// Note: parsing the stringified addresses is an expensive operation.
// Note: parsing the stringified URIs is an expensive operation.
// To mitigate that, the resulting array is stored in the memory cache.
var key = string.Concat("851d6f08-2ee0-4452-bbe5-ab864611ecaa", "\x1e", application.RedirectUris);
var addresses = Cache.GetOrCreate(key, entry =>
var uris = Cache.GetOrCreate(key, entry =>
{
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
@ -620,7 +620,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
return builder.ToImmutable();
});
return new(addresses);
return new(uris);
}
/// <inheritdoc/>
@ -853,14 +853,14 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
/// <inheritdoc/>
public virtual ValueTask SetPostLogoutRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> uris, CancellationToken cancellationToken)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (addresses.IsDefaultOrEmpty)
if (uris.IsDefaultOrEmpty)
{
application.PostLogoutRedirectUris = null;
@ -876,9 +876,9 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
writer.WriteStartArray();
foreach (var address in addresses)
foreach (var uri in uris)
{
writer.WriteStringValue(address);
writer.WriteStringValue(uri);
}
writer.WriteEndArray();
@ -930,14 +930,14 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
/// <inheritdoc/>
public virtual ValueTask SetRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> uris, CancellationToken cancellationToken)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (addresses.IsDefaultOrEmpty)
if (uris.IsDefaultOrEmpty)
{
application.RedirectUris = null;
@ -953,9 +953,9 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<TApplication, TAuthor
writer.WriteStartArray();
foreach (var address in addresses)
foreach (var uri in uris)
{
writer.WriteStringValue(address);
writer.WriteStringValue(uri);
}
writer.WriteEndArray();

4
src/OpenIddict.MongoDb.Models/OpenIddictMongoDbApplication.cs

@ -67,7 +67,7 @@ public class OpenIddictMongoDbApplication
public virtual IReadOnlyList<string>? Permissions { get; set; } = ImmutableList.Create<string>();
/// <summary>
/// Gets or sets the logout callback URLs associated with the current application.
/// Gets or sets the post-logout redirect URIs associated with the current application.
/// </summary>
[BsonElement("post_logout_redirect_uris"), BsonIgnoreIfNull]
public virtual IReadOnlyList<string>? PostLogoutRedirectUris { get; set; } = ImmutableList.Create<string>();
@ -79,7 +79,7 @@ public class OpenIddictMongoDbApplication
public virtual BsonDocument? Properties { get; set; }
/// <summary>
/// Gets or sets the callback URLs associated with the current application.
/// Gets or sets the redirect URIs associated with the current application.
/// </summary>
[BsonElement("redirect_uris"), BsonIgnoreIfNull]
public virtual IReadOnlyList<string>? RedirectUris { get; set; } = ImmutableList.Create<string>();

28
src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs

@ -138,11 +138,11 @@ public class OpenIddictMongoDbApplicationStore<TApplication> : IOpenIddictApplic
/// <inheritdoc/>
public virtual IAsyncEnumerable<TApplication> FindByPostLogoutRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
return ExecuteAsync(cancellationToken);
@ -153,7 +153,7 @@ public class OpenIddictMongoDbApplicationStore<TApplication> : IOpenIddictApplic
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName);
await foreach (var application in collection.Find(application =>
application.PostLogoutRedirectUris!.Contains(address)).ToAsyncEnumerable(cancellationToken))
application.PostLogoutRedirectUris!.Contains(uri)).ToAsyncEnumerable(cancellationToken))
{
yield return application;
}
@ -162,11 +162,11 @@ public class OpenIddictMongoDbApplicationStore<TApplication> : IOpenIddictApplic
/// <inheritdoc/>
public virtual IAsyncEnumerable<TApplication> FindByRedirectUriAsync(
[StringSyntax(StringSyntaxAttribute.Uri)] string address, CancellationToken cancellationToken)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(uri));
}
return ExecuteAsync(cancellationToken);
@ -177,7 +177,7 @@ public class OpenIddictMongoDbApplicationStore<TApplication> : IOpenIddictApplic
var collection = database.GetCollection<TApplication>(Options.CurrentValue.ApplicationsCollectionName);
await foreach (var application in collection.Find(application =>
application.RedirectUris!.Contains(address)).ToAsyncEnumerable(cancellationToken))
application.RedirectUris!.Contains(uri)).ToAsyncEnumerable(cancellationToken))
{
yield return application;
}
@ -554,21 +554,21 @@ public class OpenIddictMongoDbApplicationStore<TApplication> : IOpenIddictApplic
/// <inheritdoc/>
public virtual ValueTask SetPostLogoutRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> uris, CancellationToken cancellationToken)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (addresses.IsDefaultOrEmpty)
if (uris.IsDefaultOrEmpty)
{
application.PostLogoutRedirectUris = null;
return default;
}
application.PostLogoutRedirectUris = addresses.ToImmutableList();
application.PostLogoutRedirectUris = uris.ToImmutableList();
return default;
}
@ -614,21 +614,21 @@ public class OpenIddictMongoDbApplicationStore<TApplication> : IOpenIddictApplic
/// <inheritdoc/>
public virtual ValueTask SetRedirectUrisAsync(TApplication application,
ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> uris, CancellationToken cancellationToken)
{
if (application is null)
{
throw new ArgumentNullException(nameof(application));
}
if (addresses.IsDefaultOrEmpty)
if (uris.IsDefaultOrEmpty)
{
application.RedirectUris = null;
return default;
}
application.RedirectUris = addresses.ToImmutableList();
application.RedirectUris = uris.ToImmutableList();
return default;
}

2
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreBuilder.cs

@ -149,7 +149,7 @@ public sealed class OpenIddictServerAspNetCoreBuilder
/// <summary>
/// Sets the realm returned to the caller as part of the WWW-Authenticate header.
/// </summary>
/// <param name="realm">The issuer address.</param>
/// <param name="realm">The realm.</param>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/> instance.</returns>
public OpenIddictServerAspNetCoreBuilder SetRealm(string realm)
{

4
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs

@ -245,12 +245,12 @@ public static partial class OpenIddictServerAspNetCoreHandlers
token, _options.CurrentValue.AuthorizationRequestCachingPolicy);
// Create a new GET authorization request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString(
var location = QueryHelpers.AddQueryString(
uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path,
name: Parameters.RequestId,
value: context.Request.RequestId);
request.HttpContext.Response.Redirect(address);
request.HttpContext.Response.Redirect(location);
// Mark the response as handled to skip the rest of the pipeline.
context.HandleRequest();

4
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Device.cs

@ -81,8 +81,8 @@ public static partial class OpenIddictServerAspNetCoreHandlers
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0114));
// Note: this handler only redirects the user agent to the address specified in
// the properties when there's no error or if the error is an access_denied error.
// Note: this handler only redirects the user agent to the URI specified in the
// properties when there's no error or if the error is an access_denied error.
if (!string.IsNullOrEmpty(context.Response.Error) &&
!string.Equals(context.Response.Error, Errors.AccessDenied, StringComparison.Ordinal))
{

4
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs

@ -242,12 +242,12 @@ public static partial class OpenIddictServerAspNetCoreHandlers
token, _options.CurrentValue.LogoutRequestCachingPolicy);
// Create a new GET logout request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString(
var location = QueryHelpers.AddQueryString(
uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path,
name: Parameters.RequestId,
value: context.Request.RequestId);
request.HttpContext.Response.Redirect(address);
request.HttpContext.Response.Redirect(location);
// Mark the response as handled to skip the rest of the pipeline.
context.HandleRequest();

2
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs

@ -96,7 +96,7 @@ public static partial class OpenIddictServerAspNetCoreHandlers
// sent by the HTTP client) is not desirable as it would affect all requests, including requests
// that are not meant to be handled by OpenIddict itself. To avoid that, a fake host is temporarily
// used to build an absolute base URI and a request URI that will be used to determine whether the
// received request matches one of the addresses assigned to an OpenIddict endpoint. If the request
// received request matches one of the URIs assigned to an OpenIddict endpoint. If the request
// is later handled by OpenIddict, an additional check will be made to require the Host header.
(context.BaseUri, context.RequestUri) = request.Host switch

2
src/OpenIddict.Server.Owin/OpenIddictServerOwinBuilder.cs

@ -138,7 +138,7 @@ public sealed class OpenIddictServerOwinBuilder
/// <summary>
/// Sets the realm returned to the caller as part of the WWW-Authenticate header.
/// </summary>
/// <param name="realm">The issuer address.</param>
/// <param name="realm">The realm.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/> instance.</returns>
public OpenIddictServerOwinBuilder SetRealm(string realm)
{

4
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs

@ -241,12 +241,12 @@ public static partial class OpenIddictServerOwinHandlers
token, _options.CurrentValue.AuthorizationRequestCachingPolicy);
// Create a new GET authorization request containing only the request_id parameter.
var address = WebUtilities.AddQueryString(
var location = WebUtilities.AddQueryString(
uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path,
name: Parameters.RequestId,
value: context.Request.RequestId);
request.Context.Response.Redirect(address);
request.Context.Response.Redirect(location);
// Mark the response as handled to skip the rest of the pipeline.
context.HandleRequest();

4
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Device.cs

@ -84,8 +84,8 @@ public static partial class OpenIddictServerOwinHandlers
var response = context.Transaction.GetOwinRequest()?.Context.Response ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0120));
// Note: this handler only redirects the user agent to the address specified in
// the properties when there's no error or if the error is an access_denied error.
// Note: this handler only redirects the user agent to the URI specified in the
// properties when there's no error or if the error is an access_denied error.
if (!string.IsNullOrEmpty(context.Response.Error) &&
!string.Equals(context.Response.Error, Errors.AccessDenied, StringComparison.Ordinal))
{

4
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs

@ -239,12 +239,12 @@ public static partial class OpenIddictServerOwinHandlers
token, _options.CurrentValue.LogoutRequestCachingPolicy);
// Create a new GET logout request containing only the request_id parameter.
var address = WebUtilities.AddQueryString(
var location = WebUtilities.AddQueryString(
uri: request.Scheme + Uri.SchemeDelimiter + request.Host + request.PathBase + request.Path,
name: Parameters.RequestId,
value: context.Request.RequestId);
request.Context.Response.Redirect(address);
request.Context.Response.Redirect(location);
// Mark the response as handled to skip the rest of the pipeline.
context.HandleRequest();

2
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs

@ -91,7 +91,7 @@ public static partial class OpenIddictServerOwinHandlers
// sent by the HTTP client) is not desirable as it would affect all requests, including requests
// that are not meant to be handled by OpenIddict itself. To avoid that, a fake host is temporarily
// used to build an absolute base URI and a request URI that will be used to determine whether the
// received request matches one of the addresses assigned to an OpenIddict endpoint. If the request
// received request matches one of the URIs assigned to an OpenIddict endpoint. If the request
// is later handled by OpenIddict, an additional check will be made to require the Host header.
(context.BaseUri, context.RequestUri) = request.Host switch

372
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -1002,492 +1002,492 @@ public sealed class OpenIddictServerBuilder
});
/// <summary>
/// Sets the relative or absolute URLs associated to the authorization endpoint.
/// Sets the relative or absolute URIs associated to the authorization endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetAuthorizationEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetAuthorizationEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetAuthorizationEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the authorization endpoint.
/// Sets the relative or absolute URIs associated to the authorization endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetAuthorizationEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetAuthorizationEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.AuthorizationEndpointUris.Clear();
options.AuthorizationEndpointUris.AddRange(addresses);
options.AuthorizationEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the configuration endpoint.
/// Sets the relative or absolute URIs associated to the configuration endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetConfigurationEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetConfigurationEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetConfigurationEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the configuration endpoint.
/// Sets the relative or absolute URIs associated to the configuration endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetConfigurationEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetConfigurationEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.ConfigurationEndpointUris.Clear();
options.ConfigurationEndpointUris.AddRange(addresses);
options.ConfigurationEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the cryptography endpoint.
/// Sets the relative or absolute URIs associated to the cryptography endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetCryptographyEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetCryptographyEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetCryptographyEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the cryptography endpoint.
/// Sets the relative or absolute URIs associated to the cryptography endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetCryptographyEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetCryptographyEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.CryptographyEndpointUris.Clear();
options.CryptographyEndpointUris.AddRange(addresses);
options.CryptographyEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the device endpoint.
/// Sets the relative or absolute URIs associated to the device endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetDeviceEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetDeviceEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetDeviceEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the device endpoint.
/// Sets the relative or absolute URIs associated to the device endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetDeviceEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetDeviceEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.DeviceEndpointUris.Clear();
options.DeviceEndpointUris.AddRange(addresses);
options.DeviceEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the introspection endpoint.
/// Sets the relative or absolute URIs associated to the introspection endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetIntrospectionEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetIntrospectionEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetIntrospectionEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the introspection endpoint.
/// Sets the relative or absolute URIs associated to the introspection endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetIntrospectionEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetIntrospectionEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.IntrospectionEndpointUris.Clear();
options.IntrospectionEndpointUris.AddRange(addresses);
options.IntrospectionEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the logout endpoint.
/// Sets the relative or absolute URIs associated to the logout endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetLogoutEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetLogoutEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetLogoutEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the logout endpoint.
/// Sets the relative or absolute URIs associated to the logout endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetLogoutEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetLogoutEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.LogoutEndpointUris.Clear();
options.LogoutEndpointUris.AddRange(addresses);
options.LogoutEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the revocation endpoint.
/// Sets the relative or absolute URIs associated to the revocation endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetRevocationEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetRevocationEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetRevocationEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the revocation endpoint.
/// Sets the relative or absolute URIs associated to the revocation endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetRevocationEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetRevocationEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.RevocationEndpointUris.Clear();
options.RevocationEndpointUris.AddRange(addresses);
options.RevocationEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the token endpoint.
/// Sets the relative or absolute URIs associated to the token endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetTokenEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetTokenEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetTokenEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the token endpoint.
/// Sets the relative or absolute URIs associated to the token endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetTokenEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetTokenEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.TokenEndpointUris.Clear();
options.TokenEndpointUris.AddRange(addresses);
options.TokenEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the userinfo endpoint.
/// Sets the relative or absolute URIs associated to the userinfo endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetUserinfoEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetUserinfoEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetUserinfoEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the userinfo endpoint.
/// Sets the relative or absolute URIs associated to the userinfo endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned as part of the discovery document.
/// Note: only the first URI will be returned as part of the discovery document.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetUserinfoEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetUserinfoEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.UserinfoEndpointUris.Clear();
options.UserinfoEndpointUris.AddRange(addresses);
options.UserinfoEndpointUris.AddRange(uris);
});
}
/// <summary>
/// Sets the relative or absolute URLs associated to the verification endpoint.
/// Sets the relative or absolute URIs associated to the verification endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned by the device endpoint.
/// Note: only the first URI will be returned by the device endpoint.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetVerificationEndpointUris(
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] addresses)
[StringSyntax(StringSyntaxAttribute.Uri)] params string[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
return SetVerificationEndpointUris(addresses.Select(address => new Uri(address, UriKind.RelativeOrAbsolute)).ToArray());
return SetVerificationEndpointUris(uris.Select(uri => new Uri(uri, UriKind.RelativeOrAbsolute)).ToArray());
}
/// <summary>
/// Sets the relative or absolute URLs associated to the verification endpoint.
/// Sets the relative or absolute URIs associated to the verification endpoint.
/// If an empty array is specified, the endpoint will be considered disabled.
/// Note: only the first address will be returned by the device endpoint.
/// Note: only the first URI will be returned by the device endpoint.
/// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param>
/// <param name="uris">The URIs associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetVerificationEndpointUris(params Uri[] addresses)
public OpenIddictServerBuilder SetVerificationEndpointUris(params Uri[] uris)
{
if (addresses is null)
if (uris is null)
{
throw new ArgumentNullException(nameof(addresses));
throw new ArgumentNullException(nameof(uris));
}
if (addresses.Any(address => !address.IsWellFormedOriginalString()))
if (uris.Any(uri => !uri.IsWellFormedOriginalString()))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(addresses));
throw new ArgumentException(SR.GetResourceString(SR.ID0072), nameof(uris));
}
if (addresses.Any(address => address.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
if (uris.Any(uri => uri.OriginalString.StartsWith("~", StringComparison.OrdinalIgnoreCase)))
{
throw new ArgumentException(SR.FormatID0081("~"), nameof(addresses));
throw new ArgumentException(SR.FormatID0081("~"), nameof(uris));
}
return Configure(options =>
{
options.VerificationEndpointUris.Clear();
options.VerificationEndpointUris.AddRange(addresses);
options.VerificationEndpointUris.AddRange(uris);
});
}
@ -1714,19 +1714,19 @@ public sealed class OpenIddictServerBuilder
=> Configure(options => options.UserCodeLifetime = lifetime);
/// <summary>
/// Sets the issuer address, which is used as the value for the "issuer" claim and
/// Sets the issuer URI, which is used as the value of the "issuer" claim and
/// is returned from the discovery endpoint to identify the authorization server.
/// </summary>
/// <param name="address">The issuer address.</param>
/// <param name="uri">The issuer uri.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetIssuer(Uri address)
public OpenIddictServerBuilder SetIssuer(Uri uri)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
return Configure(options => options.Issuer = address);
return Configure(options => options.Issuer = uri);
}
/// <summary>

6
src/OpenIddict.Server/OpenIddictServerConfiguration.cs

@ -57,7 +57,7 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions<OpenId
throw new InvalidOperationException(SR.GetResourceString(SR.ID0076));
}
var addresses = options.AuthorizationEndpointUris.Distinct()
var uris = options.AuthorizationEndpointUris.Distinct()
.Concat(options.ConfigurationEndpointUris.Distinct())
.Concat(options.CryptographyEndpointUris.Distinct())
.Concat(options.DeviceEndpointUris.Distinct())
@ -69,8 +69,8 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions<OpenId
.Concat(options.VerificationEndpointUris.Distinct())
.ToList();
// Ensure endpoint addresses are unique across endpoints.
if (addresses.Count != addresses.Distinct().Count())
// Ensure endpoint URIs are unique across endpoints.
if (uris.Count != uris.Distinct().Count())
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0285));
}

18
src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs

@ -80,23 +80,23 @@ public static partial class OpenIddictServerEvents
/// <summary>
/// Populates the <see cref="RedirectUri"/> property with the specified redirect_uri.
/// </summary>
/// <param name="address">The redirect_uri to use when redirecting the user agent.</param>
public void SetRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string address)
/// <param name="uri">The redirect_uri to use when redirecting the user agent.</param>
public void SetRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0100), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0100), nameof(uri));
}
// Don't allow validation to alter the redirect_uri parameter extracted
// from the request if the address was explicitly provided by the client.
// from the request if the URI was explicitly provided by the client.
if (!string.IsNullOrEmpty(Request?.RedirectUri) &&
!string.Equals(Request.RedirectUri, address, StringComparison.Ordinal))
!string.Equals(Request.RedirectUri, uri, StringComparison.Ordinal))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0101));
}
RedirectUri = address;
RedirectUri = uri;
}
}
@ -206,10 +206,10 @@ public static partial class OpenIddictServerEvents
public string? Error => Response?.Error;
/// <summary>
/// Gets or sets the callback URL the user agent will be redirected to, if applicable.
/// Gets or sets the redirect URI the user agent will be redirected to, if applicable.
/// Note: manually changing the value of this property is generally not recommended
/// and extreme caution must be taken to ensure the user agent is not redirected to
/// an untrusted address, which would result in an "open redirection" vulnerability.
/// an untrusted URI, which would result in an "open redirection" vulnerability.
/// </summary>
public string? RedirectUri { get; set; }

18
src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs

@ -87,47 +87,47 @@ public static partial class OpenIddictServerEvents
public Dictionary<string, OpenIddictParameter> Metadata { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the issuer address.
/// Gets or sets the issuer URI.
/// </summary>
public Uri? Issuer { get; set; }
/// <summary>
/// Gets or sets the authorization endpoint address.
/// Gets or sets the authorization endpoint URI.
/// </summary>
public Uri? AuthorizationEndpoint { get; set; }
/// <summary>
/// Gets or sets the JWKS endpoint address.
/// Gets or sets the JWKS endpoint URI.
/// </summary>
public Uri? CryptographyEndpoint { get; set; }
/// <summary>
/// Gets or sets the device endpoint address.
/// Gets or sets the device endpoint URI.
/// </summary>
public Uri? DeviceEndpoint { get; set; }
/// <summary>
/// Gets or sets the introspection endpoint address.
/// Gets or sets the introspection endpoint URI.
/// </summary>
public Uri? IntrospectionEndpoint { get; set; }
/// <summary>
/// Gets or sets the logout endpoint address.
/// Gets or sets the logout endpoint URI.
/// </summary>
public Uri? LogoutEndpoint { get; set; }
/// <summary>
/// Gets or sets the revocation endpoint address.
/// Gets or sets the revocation endpoint URI.
/// </summary>
public Uri? RevocationEndpoint { get; set; }
/// <summary>
/// Gets or sets the token endpoint address.
/// Gets or sets the token endpoint URI.
/// </summary>
public Uri? TokenEndpoint { get; set; }
/// <summary>
/// Gets or sets the userinfo endpoint address.
/// Gets or sets the userinfo endpoint URI.
/// </summary>
public Uri? UserinfoEndpoint { get; set; }

18
src/OpenIddict.Server/OpenIddictServerEvents.Session.cs

@ -78,23 +78,23 @@ public static partial class OpenIddictServerEvents
/// <summary>
/// Populates the <see cref="PostLogoutRedirectUri"/> property with the specified redirect_uri.
/// </summary>
/// <param name="address">The post_logout_redirect_uri to use when redirecting the user agent.</param>
public void SetPostLogoutRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string address)
/// <param name="uri">The post_logout_redirect_uri to use when redirecting the user agent.</param>
public void SetPostLogoutRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0102), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0102), nameof(uri));
}
// Don't allow validation to alter the post_logout_redirect_uri parameter extracted
// from the request if the address was explicitly provided by the client application.
// from the request if the URI was explicitly provided by the client application.
if (!string.IsNullOrEmpty(Request?.PostLogoutRedirectUri) &&
!string.Equals(Request.PostLogoutRedirectUri, address, StringComparison.Ordinal))
!string.Equals(Request.PostLogoutRedirectUri, uri, StringComparison.Ordinal))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0103));
}
PostLogoutRedirectUri = address;
PostLogoutRedirectUri = uri;
}
}
@ -193,10 +193,10 @@ public static partial class OpenIddictServerEvents
public string? Error => Response.Error;
/// <summary>
/// Gets or sets the callback URL the user agent will be redirected to, if applicable.
/// Gets or sets the post-logout redirect URI the user agent will be redirected to, if applicable.
/// Note: manually changing the value of this property is generally not recommended
/// and extreme caution must be taken to ensure the user agent is not redirected to
/// an untrusted address, which would result in an "open redirection" vulnerability.
/// an untrusted URI, which would result in an "open redirection" vulnerability.
/// </summary>
public string? PostLogoutRedirectUri { get; set; }
}

2
src/OpenIddict.Server/OpenIddictServerEvents.cs

@ -266,7 +266,7 @@ public static partial class OpenIddictServerEvents
public string? ErrorDescription { get; set; }
/// <summary>
/// Gets or sets the error URL returned to the caller.
/// Gets or sets the error URI returned to the caller.
/// </summary>
public string? ErrorUri { get; set; }

18
src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs

@ -510,7 +510,7 @@ public static partial class OpenIddictServerHandlers
// See http://tools.ietf.org/html/rfc6749#section-3.1.2
// and http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest.
//
// Note: on Linux/macOS, "/path" URLs are treated as valid absolute file URLs.
// Note: on Linux/macOS, "/path" URIs are treated as valid absolute file URIs.
// To ensure relative redirect_uris are correctly rejected on these platforms,
// an additional check using IsWellFormedOriginalString() is made here.
// See https://github.com/dotnet/corefx/issues/22098 for more information.
@ -1168,12 +1168,12 @@ public static partial class OpenIddictServerHandlers
var application = await _applicationManager.FindByClientIdAsync(context.ClientId) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// If no explicit redirect_uri was specified, retrieve the addresses associated with
// the client and ensure exactly one redirect_uri was attached to the client definition.
// If no explicit redirect_uri was specified, retrieve the URI associated with the
// client and ensure exactly one redirect_uri was attached to the client definition.
if (string.IsNullOrEmpty(context.RedirectUri))
{
var addresses = await _applicationManager.GetRedirectUrisAsync(application);
if (addresses.Length is not 1)
var uris = await _applicationManager.GetRedirectUrisAsync(application);
if (uris.Length is not 1)
{
context.Logger.LogInformation(SR.GetResourceString(SR.ID6033), Parameters.RedirectUri);
@ -1185,7 +1185,7 @@ public static partial class OpenIddictServerHandlers
return;
}
context.SetRedirectUri(addresses[0]);
context.SetRedirectUri(uris[0]);
return;
}
@ -1782,7 +1782,7 @@ public static partial class OpenIddictServerHandlers
}
/// <summary>
/// Contains the logic responsible for inferring the redirect URL
/// Contains the logic responsible for inferring the redirect URI
/// used to send the response back to the client application.
/// </summary>
public sealed class AttachRedirectUri : IOpenIddictServerHandler<ApplyAuthorizationResponseContext>
@ -1905,7 +1905,7 @@ public static partial class OpenIddictServerHandlers
/// <summary>
/// Contains the logic responsible for attaching an "iss" parameter
/// containing the address of the authorization server to the response.
/// containing the URI of the authorization server to the response.
/// </summary>
public sealed class AttachIssuer : IOpenIddictServerHandler<ApplyAuthorizationResponseContext>
{
@ -1928,7 +1928,7 @@ public static partial class OpenIddictServerHandlers
}
// If the user agent is expected to be redirected to the client application, attach the
// issuer address to the authorization response to help the client detect mix-up attacks.
// issuer URI to the authorization response to help the client detect mix-up attacks.
//
// Note: this applies to all authorization responses, whether they represent valid or errored responses.
// For more information, see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-iss-auth-resp-05.

8
src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs

@ -341,7 +341,7 @@ public static partial class OpenIddictServerHandlers
}
/// <summary>
/// Contains the logic responsible for attaching the endpoint URLs to the provider discovery document.
/// Contains the logic responsible for attaching the endpoint URIs to the provider discovery document.
/// </summary>
public sealed class AttachEndpoints : IOpenIddictServerHandler<HandleConfigurationRequestContext>
{
@ -363,8 +363,8 @@ public static partial class OpenIddictServerHandlers
throw new ArgumentNullException(nameof(context));
}
// Note: while OpenIddict allows specifying multiple endpoint addresses, the OAuth 2.0
// and OpenID Connect discovery specifications only allow a single address per endpoint.
// Note: while OpenIddict allows specifying multiple endpoint URIs, the OAuth 2.0
// and OpenID Connect discovery specifications only allow a single URI per endpoint.
context.AuthorizationEndpoint ??= OpenIddictHelpers.CreateAbsoluteUri(
context.BaseUri, context.Options.AuthorizationEndpointUris.FirstOrDefault());
@ -739,7 +739,7 @@ public static partial class OpenIddictServerHandlers
context.Metadata[Metadata.RequestParameterSupported] = false;
context.Metadata[Metadata.RequestUriParameterSupported] = false;
// As of 3.2.0, OpenIddict automatically returns an "iss" parameter containing its own address as
// As of 3.2.0, OpenIddict automatically returns an "iss" parameter containing its identity as
// part of authorization responses to help clients mitigate mix-up attacks. For more information,
// see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-iss-auth-resp-05.
context.Metadata[Metadata.AuthorizationResponseIssParameterSupported] = true;

6
src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs

@ -1486,8 +1486,8 @@ public static partial class OpenIddictServerHandlers
// if the authorization request didn't contain an explicit redirect_uri.
// See https://tools.ietf.org/html/rfc6749#section-4.1.3
// and http://openid.net/specs/openid-connect-core-1_0.html#TokenRequestValidation.
var address = context.Principal.GetClaim(Claims.Private.RedirectUri);
if (string.IsNullOrEmpty(address))
var uri = context.Principal.GetClaim(Claims.Private.RedirectUri);
if (string.IsNullOrEmpty(uri))
{
return default;
}
@ -1504,7 +1504,7 @@ public static partial class OpenIddictServerHandlers
return default;
}
if (!string.Equals(address, context.Request.RedirectUri, StringComparison.Ordinal))
if (!string.Equals(uri, context.Request.RedirectUri, StringComparison.Ordinal))
{
context.Logger.LogInformation(SR.GetResourceString(SR.ID6092), Parameters.RedirectUri);

12
src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs

@ -472,7 +472,7 @@ public static partial class OpenIddictServerHandlers
//
// * The client_id parameter is supported by the client and was explicitly sent:
// in this case, the post_logout_redirect_uris allowed for this client application
// are retrieved from the database: if one of them matches the specified address,
// are retrieved from the database: if one of them matches the specified URI,
// the request is considered valid. Otherwise, it's automatically rejected.
//
// * The client_id parameter is not supported by the client or was not explicitly sent:
@ -514,12 +514,12 @@ public static partial class OpenIddictServerHandlers
return;
}
async ValueTask<bool> ValidatePostLogoutRedirectUriAsync([StringSyntax(StringSyntaxAttribute.Uri)] string address)
async ValueTask<bool> ValidatePostLogoutRedirectUriAsync([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
// To be considered valid, a post_logout_redirect_uri must correspond to an existing client application
// that was granted the ept:logout permission, unless endpoint permissions checking was explicitly disabled.
await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(address))
await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(uri))
{
if (context.Options.IgnoreEndpointPermissions ||
await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Logout))
@ -755,12 +755,12 @@ public static partial class OpenIddictServerHandlers
}
async ValueTask<bool> ValidateAuthorizedParty(ClaimsPrincipal principal,
[StringSyntax(StringSyntaxAttribute.Uri)] string address)
[StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
// To be considered valid, one of the clients matching the specified post_logout_redirect_uri
// must be listed either as an audience or as a presenter in the identity token hint.
await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(address))
await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(uri))
{
var identifier = await _applicationManager.GetClientIdAsync(application);
if (!string.IsNullOrEmpty(identifier) && (principal.HasAudience(identifier) ||
@ -810,7 +810,7 @@ public static partial class OpenIddictServerHandlers
}
/// <summary>
/// Contains the logic responsible for inferring the redirect URL
/// Contains the logic responsible for inferring the redirect URI
/// used to send the response back to the client application.
/// </summary>
public sealed class AttachPostLogoutRedirectUri : IOpenIddictServerHandler<ApplyLogoutResponseContext>

23
src/OpenIddict.Server/OpenIddictServerHandlers.cs

@ -106,7 +106,7 @@ public static partial class OpenIddictServerHandlers
.AddRange(Userinfo.DefaultHandlers);
/// <summary>
/// Contains the logic responsible for inferring the endpoint type from the request address.
/// Contains the logic responsible for inferring the endpoint type from the request URI.
/// </summary>
public sealed class InferEndpointType : IOpenIddictServerHandler<ProcessRequestContext>
{
@ -153,14 +153,14 @@ public static partial class OpenIddictServerHandlers
return default;
bool Matches(IReadOnlyList<Uri> addresses)
bool Matches(IReadOnlyList<Uri> candidates)
{
for (var index = 0; index < addresses.Count; index++)
for (var index = 0; index < candidates.Count; index++)
{
var address = addresses[index];
if (address.IsAbsoluteUri)
var candidate = candidates[index];
if (candidate.IsAbsoluteUri)
{
if (Equals(address, context.RequestUri))
if (Equals(candidate, context.RequestUri))
{
return true;
}
@ -168,7 +168,7 @@ public static partial class OpenIddictServerHandlers
else
{
var uri = OpenIddictHelpers.CreateAbsoluteUri(context.BaseUri, address);
var uri = OpenIddictHelpers.CreateAbsoluteUri(context.BaseUri, candidate);
if (uri.IsWellFormedOriginalString() &&
OpenIddictHelpers.IsBaseOf(context.BaseUri, uri) && Equals(uri, context.RequestUri))
{
@ -3073,16 +3073,15 @@ public static partial class OpenIddictServerHandlers
{
context.Response.UserCode = context.UserCode;
var address = OpenIddictHelpers.CreateAbsoluteUri(context.BaseUri,
context.Options.VerificationEndpointUris.FirstOrDefault());
if (address is not null)
if (OpenIddictHelpers.CreateAbsoluteUri(context.BaseUri,
context.Options.VerificationEndpointUris.FirstOrDefault()) is Uri uri)
{
var builder = new UriBuilder(address)
var builder = new UriBuilder(uri)
{
Query = string.Concat(Parameters.UserCode, "=", context.UserCode)
};
context.Response[Parameters.VerificationUri] = address.AbsoluteUri;
context.Response[Parameters.VerificationUri] = uri.AbsoluteUri;
context.Response[Parameters.VerificationUriComplete] = builder.Uri.AbsoluteUri;
}
}

2
src/OpenIddict.Server/OpenIddictServerOptions.cs

@ -16,7 +16,7 @@ namespace OpenIddict.Server;
public sealed class OpenIddictServerOptions
{
/// <summary>
/// Gets or sets the optional address used to uniquely identify the authorization server.
/// Gets or sets the optional URI used to uniquely identify the authorization server.
/// The URI must be absolute and may contain a path, but no query string or fragment part.
/// </summary>
public Uri? Issuer { get; set; }

2
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreBuilder.cs

@ -49,7 +49,7 @@ public sealed class OpenIddictValidationAspNetCoreBuilder
/// <summary>
/// Sets the realm returned to the caller as part of the WWW-Authenticate header.
/// </summary>
/// <param name="realm">The issuer address.</param>
/// <param name="realm">The realm.</param>
/// <returns>The <see cref="OpenIddictValidationAspNetCoreBuilder"/> instance.</returns>
public OpenIddictValidationAspNetCoreBuilder SetRealm(string realm)
{

2
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs

@ -96,7 +96,7 @@ public static partial class OpenIddictValidationAspNetCoreHandlers
// sent by the HTTP client) is not desirable as it would affect all requests, including requests
// that are not meant to be handled by OpenIddict itself. To avoid that, a fake host is temporarily
// used to build an absolute base URI and a request URI that will be used to determine whether the
// received request matches one of the addresses assigned to an OpenIddict endpoint. If the request
// received request matches one of the URIs assigned to an OpenIddict endpoint. If the request
// is later handled by OpenIddict, an additional check will be made to require the Host header.
(context.BaseUri, context.RequestUri) = request.Host switch

2
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinBuilder.cs

@ -64,7 +64,7 @@ public sealed class OpenIddictValidationOwinBuilder
/// <summary>
/// Sets the realm returned to the caller as part of the WWW-Authenticate header.
/// </summary>
/// <param name="realm">The issuer address.</param>
/// <param name="realm">The realm.</param>
/// <returns>The <see cref="OpenIddictValidationOwinBuilder"/> instance.</returns>
public OpenIddictValidationOwinBuilder SetRealm(string realm)
{

2
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs

@ -94,7 +94,7 @@ public static partial class OpenIddictValidationOwinHandlers
// sent by the HTTP client) is not desirable as it would affect all requests, including requests
// that are not meant to be handled by OpenIddict itself. To avoid that, a fake host is temporarily
// used to build an absolute base URI and a request URI that will be used to determine whether the
// received request matches one of the addresses assigned to an OpenIddict endpoint. If the request
// received request matches one of the URIs assigned to an OpenIddict endpoint. If the request
// is later handled by OpenIddict, an additional check will be made to require the Host header.
(context.BaseUri, context.RequestUri) = request.Host switch

2
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpExtensions.cs

@ -37,7 +37,7 @@ public static class OpenIddictValidationSystemNetHttpExtensions
builder.Services.TryAdd(OpenIddictValidationSystemNetHttpHandlers.DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));
// Register the built-in filters used by the default OpenIddict System.Net.Http event handlers.
builder.Services.TryAddSingleton<RequireHttpMetadataAddress>();
builder.Services.TryAddSingleton<RequireHttpMetadataUri>();
// Note: TryAddEnumerable() is used here to ensure the initializers are registered only once.
builder.Services.TryAddEnumerable(new[]

8
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlerFilters.cs

@ -12,9 +12,9 @@ namespace OpenIddict.Validation.SystemNetHttp;
public static class OpenIddictValidationSystemNetHttpHandlerFilters
{
/// <summary>
/// Represents a filter that excludes the associated handlers if the metadata address of the issuer is not available.
/// Represents a filter that excludes the associated handlers if the metadata URI of the issuer is not available.
/// </summary>
public sealed class RequireHttpMetadataAddress : IOpenIddictValidationHandlerFilter<BaseExternalContext>
public sealed class RequireHttpMetadataUri : IOpenIddictValidationHandlerFilter<BaseExternalContext>
{
public ValueTask<bool> IsActiveAsync(BaseExternalContext context)
{
@ -24,8 +24,8 @@ public static class OpenIddictValidationSystemNetHttpHandlerFilters
}
return new(
string.Equals(context.Address?.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
string.Equals(context.Address?.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase));
string.Equals(context.RemoteUri?.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
string.Equals(context.RemoteUri?.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase));
}
}
}

2
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs

@ -46,7 +46,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<PrepareIntrospectionRequestContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachBasicAuthenticationCredentials>()
.SetOrder(AttachFormParameters<PrepareIntrospectionRequestContext>.Descriptor.Order - 500)
.SetType(OpenIddictValidationHandlerType.BuiltIn)

30
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs

@ -35,7 +35,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<PrepareGetHttpRequest<TContext>>()
.SetOrder(int.MinValue + 100_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -51,7 +51,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
// Store the HttpRequestMessage in the transaction properties.
context.Transaction.SetProperty(typeof(HttpRequestMessage).FullName!,
new HttpRequestMessage(HttpMethod.Get, context.Address));
new HttpRequestMessage(HttpMethod.Get, context.RemoteUri));
return default;
}
@ -67,7 +67,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<PreparePostHttpRequest<TContext>>()
.SetOrder(PrepareGetHttpRequest<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -83,7 +83,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
// Store the HttpRequestMessage in the transaction properties.
context.Transaction.SetProperty(typeof(HttpRequestMessage).FullName!,
new HttpRequestMessage(HttpMethod.Post, context.Address));
new HttpRequestMessage(HttpMethod.Post, context.RemoteUri));
return default;
}
@ -100,7 +100,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachJsonAcceptHeaders<TContext>>()
.SetOrder(PreparePostHttpRequest<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -145,7 +145,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachUserAgentHeader<TContext>>()
.SetOrder(AttachJsonAcceptHeaders<TContext>.Descriptor.Order + 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -196,7 +196,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachQueryStringParameters<TContext>>()
.SetOrder(AttachFormParameters<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -241,7 +241,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachFormParameters<TContext>>()
.SetOrder(int.MaxValue - 100_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -288,7 +288,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<SendHttpRequest<TContext>>()
.SetOrder(DisposeHttpRequest<TContext>.Descriptor.Order - 50_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -361,7 +361,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<DisposeHttpRequest<TContext>>()
.SetOrder(int.MaxValue - 100_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -399,7 +399,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<DecompressResponseContent<TContext>>()
.SetOrder(ExtractJsonHttpResponse<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -538,7 +538,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ExtractJsonHttpResponse<TContext>>()
.SetOrder(ExtractWwwAuthenticateHeader<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -606,7 +606,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ExtractWwwAuthenticateHeader<TContext>>()
.SetOrder(ValidateHttpResponse<TContext>.Descriptor.Order - 1_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -689,7 +689,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<ValidateHttpResponse<TContext>>()
.SetOrder(DisposeHttpResponse<TContext>.Descriptor.Order - 50_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)
@ -759,7 +759,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
/// </summary>
public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
= OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
.AddFilter<RequireHttpMetadataAddress>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<DisposeHttpResponse<TContext>>()
.SetOrder(int.MaxValue - 100_000)
.SetType(OpenIddictValidationHandlerType.BuiltIn)

28
src/OpenIddict.Validation/OpenIddictValidationBuilder.cs

@ -433,40 +433,40 @@ public sealed class OpenIddictValidationBuilder
}
/// <summary>
/// Sets the issuer address, which is used to determine the actual location of the
/// Sets the issuer URI, which is used to determine the actual location of the
/// OAuth 2.0/OpenID Connect configuration document when using provider discovery.
/// </summary>
/// <param name="address">The issuer address.</param>
/// <param name="uri">The issuer URI.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/> instance.</returns>
public OpenIddictValidationBuilder SetIssuer(Uri address)
public OpenIddictValidationBuilder SetIssuer(Uri uri)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
return Configure(options => options.Issuer = address);
return Configure(options => options.Issuer = uri);
}
/// <summary>
/// Sets the issuer address, which is used to determine the actual location of the
/// Sets the issuer URI, which is used to determine the actual location of the
/// OAuth 2.0/OpenID Connect configuration document when using provider discovery.
/// </summary>
/// <param name="address">The issuer address.</param>
/// <param name="uri">The issuer URI.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/> instance.</returns>
public OpenIddictValidationBuilder SetIssuer([StringSyntax(StringSyntaxAttribute.Uri)] string address)
public OpenIddictValidationBuilder SetIssuer([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
if (string.IsNullOrEmpty(address))
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0126), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0126), nameof(uri));
}
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? value) || !value.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0023), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0023), nameof(uri));
}
return SetIssuer(uri);
return SetIssuer(value);
}
/// <summary>

31
src/OpenIddict.Validation/OpenIddictValidationConfiguration.cs

@ -40,11 +40,17 @@ public sealed class OpenIddictValidationConfiguration : IPostConfigureOptions<Op
}
if (options.Configuration is null && options.ConfigurationManager is null &&
options.Issuer is null && options.MetadataAddress is null)
options.Issuer is null && options.ConfigurationEndpoint is null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0128));
}
if (options.Issuer is not null && (!string.IsNullOrEmpty(options.Issuer.Fragment) ||
!string.IsNullOrEmpty(options.Issuer.Query)))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0137));
}
if (options.ValidationType is OpenIddictValidationType.Introspection)
{
if (!options.Handlers.Exists(static descriptor => descriptor.ContextType == typeof(ApplyIntrospectionRequestContext)))
@ -52,7 +58,7 @@ public sealed class OpenIddictValidationConfiguration : IPostConfigureOptions<Op
throw new InvalidOperationException(SR.GetResourceString(SR.ID0129));
}
if (options.Issuer is null && options.MetadataAddress is null)
if (options.Issuer is null && options.ConfigurationEndpoint is null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0130));
}
@ -102,25 +108,12 @@ public sealed class OpenIddictValidationConfiguration : IPostConfigureOptions<Op
throw new InvalidOperationException(SR.GetResourceString(SR.ID0135));
}
options.MetadataAddress ??= new Uri(".well-known/openid-configuration", UriKind.Relative);
if (!options.MetadataAddress.IsAbsoluteUri)
{
if (options.Issuer is not { IsAbsoluteUri: true })
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0136));
}
if (!string.IsNullOrEmpty(options.Issuer.Fragment) || !string.IsNullOrEmpty(options.Issuer.Query))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0137));
}
options.MetadataAddress = OpenIddictHelpers.CreateAbsoluteUri(options.Issuer, options.MetadataAddress);
}
options.ConfigurationEndpoint = OpenIddictHelpers.CreateAbsoluteUri(
options.Issuer,
options.ConfigurationEndpoint ?? new Uri(".well-known/openid-configuration", UriKind.Relative));
options.ConfigurationManager = new ConfigurationManager<OpenIddictConfiguration>(
options.MetadataAddress.AbsoluteUri, new OpenIddictValidationRetriever(_service))
options.ConfigurationEndpoint.AbsoluteUri, new OpenIddictValidationRetriever(_service))
{
AutomaticRefreshInterval = ConfigurationManager<OpenIddictConfiguration>.DefaultAutomaticRefreshInterval,
RefreshInterval = ConfigurationManager<OpenIddictConfiguration>.DefaultRefreshInterval

6
src/OpenIddict.Validation/OpenIddictValidationEvents.cs

@ -130,9 +130,9 @@ public static partial class OpenIddictValidationEvents
}
/// <summary>
/// Gets or sets the address of the external endpoint to communicate with.
/// Gets or sets the URI of the external endpoint to communicate with.
/// </summary>
public Uri? Address { get; set; }
public Uri? RemoteUri { get; set; }
}
/// <summary>
@ -241,7 +241,7 @@ public static partial class OpenIddictValidationEvents
public string? ErrorDescription { get; set; }
/// <summary>
/// Gets or sets the error URL returned to the caller.
/// Gets or sets the error URI returned to the caller.
/// </summary>
public string? ErrorUri { get; set; }

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

@ -179,7 +179,7 @@ public static partial class OpenIddictValidationHandlers
throw new ArgumentNullException(nameof(context));
}
// Note: the issuer returned in the discovery document must exactly match the URL used to access it.
// Note: the issuer returned in the discovery document must exactly match the URI used to access it.
// See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation.
var issuer = (string?) context.Response[Metadata.Issuer];
@ -193,7 +193,7 @@ public static partial class OpenIddictValidationHandlers
return default;
}
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri? address))
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri? uri))
{
context.Reject(
error: Errors.ServerError,
@ -204,7 +204,7 @@ public static partial class OpenIddictValidationHandlers
}
// Ensure the issuer matches the expected value.
if (address != context.Options.Issuer)
if (uri != context.Options.Issuer)
{
context.Reject(
error: Errors.ServerError,
@ -214,14 +214,14 @@ public static partial class OpenIddictValidationHandlers
return default;
}
context.Configuration.Issuer = address;
context.Configuration.Issuer = uri;
return default;
}
}
/// <summary>
/// Contains the logic responsible for extracting the JWKS endpoint address from the discovery document.
/// Contains the logic responsible for extracting the JWKS endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractCryptographyEndpoint : IOpenIddictValidationHandler<HandleConfigurationResponseContext>
{
@ -245,8 +245,8 @@ public static partial class OpenIddictValidationHandlers
// Note: the jwks_uri node is required by the OpenID Connect discovery specification.
// See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation.
var address = (string?) context.Response[Metadata.JwksUri];
if (string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.JwksUri];
if (string.IsNullOrEmpty(endpoint))
{
context.Reject(
error: Errors.ServerError,
@ -256,7 +256,7 @@ public static partial class OpenIddictValidationHandlers
return default;
}
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,
@ -273,7 +273,7 @@ public static partial class OpenIddictValidationHandlers
}
/// <summary>
/// Contains the logic responsible for extracting the introspection endpoint address from the discovery document.
/// Contains the logic responsible for extracting the introspection endpoint URI from the discovery document.
/// </summary>
public sealed class ExtractIntrospectionEndpoint : IOpenIddictValidationHandler<HandleConfigurationResponseContext>
{
@ -295,10 +295,10 @@ public static partial class OpenIddictValidationHandlers
throw new ArgumentNullException(nameof(context));
}
var address = (string?) context.Response[Metadata.IntrospectionEndpoint];
if (!string.IsNullOrEmpty(address))
var endpoint = (string?) context.Response[Metadata.IntrospectionEndpoint];
if (!string.IsNullOrEmpty(endpoint))
{
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
context.Reject(
error: Errors.ServerError,

2
src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs

@ -320,7 +320,7 @@ public static partial class OpenIddictValidationHandlers
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID4010));
// Ensure the introspection endpoint is present and is a valid absolute URL.
// Ensure the introspection endpoint is present and is a valid absolute URI.
if (context.Configuration.IntrospectionEndpoint is not { IsAbsoluteUri: true } ||
!context.Configuration.IntrospectionEndpoint.IsWellFormedOriginalString())
{

8
src/OpenIddict.Validation/OpenIddictValidationOptions.cs

@ -79,15 +79,15 @@ public sealed class OpenIddictValidationOptions
public bool EnableTokenEntryValidation { get; set; }
/// <summary>
/// Gets or sets the absolute URL of the OAuth 2.0/OpenID Connect server.
/// Gets or sets the absolute URI of the OAuth 2.0/OpenID Connect server.
/// </summary>
public Uri? Issuer { get; set; }
/// <summary>
/// Gets or sets the URL of the OAuth 2.0/OpenID Connect server discovery endpoint.
/// When the URL is relative, <see cref="Issuer"/> must be set and absolute.
/// Gets or sets the URI of the configuration endpoint exposed by the server.
/// When the URI is relative, <see cref="Issuer"/> must be set and absolute.
/// </summary>
public Uri? MetadataAddress { get; set; }
public Uri? ConfigurationEndpoint { get; set; }
/// <summary>
/// Gets or sets the OAuth 2.0/OpenID Connect static server configuration, if applicable.

74
src/OpenIddict.Validation/OpenIddictValidationService.cs

@ -93,21 +93,21 @@ public sealed class OpenIddictValidationService
}
/// <summary>
/// Retrieves the OpenID Connect server configuration from the specified address.
/// Retrieves the OpenID Connect server configuration from the specified URI.
/// </summary>
/// <param name="address">The address of the remote metadata endpoint.</param>
/// <param name="uri">The URI of the remote metadata endpoint.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The OpenID Connect server configuration retrieved from the remote server.</returns>
internal async ValueTask<OpenIddictConfiguration> GetConfigurationAsync(Uri address, CancellationToken cancellationToken = default)
internal async ValueTask<OpenIddictConfiguration> GetConfigurationAsync(Uri uri, CancellationToken cancellationToken = default)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri)
if (!uri.IsAbsoluteUri)
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
cancellationToken.ThrowIfCancellationRequested();
@ -137,7 +137,7 @@ public sealed class OpenIddictValidationService
{
var context = new PrepareConfigurationRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request
};
@ -157,7 +157,7 @@ public sealed class OpenIddictValidationService
{
var context = new ApplyConfigurationRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request
};
@ -170,7 +170,7 @@ public sealed class OpenIddictValidationService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6186), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6186), context.RemoteUri, context.Request);
return context.Request;
}
@ -179,7 +179,7 @@ public sealed class OpenIddictValidationService
{
var context = new ExtractConfigurationResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request
};
@ -194,7 +194,7 @@ public sealed class OpenIddictValidationService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6187), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6187), context.RemoteUri, context.Response);
return context.Response;
}
@ -203,7 +203,7 @@ public sealed class OpenIddictValidationService
{
var context = new HandleConfigurationResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request,
Response = response
};
@ -238,19 +238,19 @@ public sealed class OpenIddictValidationService
/// <summary>
/// Retrieves the security keys exposed by the specified JWKS endpoint.
/// </summary>
/// <param name="address">The address of the remote metadata endpoint.</param>
/// <param name="uri">The URI of the remote metadata endpoint.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The security keys retrieved from the remote server.</returns>
internal async ValueTask<JsonWebKeySet> GetSecurityKeysAsync(Uri address, CancellationToken cancellationToken = default)
internal async ValueTask<JsonWebKeySet> GetSecurityKeysAsync(Uri uri, CancellationToken cancellationToken = default)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri)
if (!uri.IsAbsoluteUri)
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
cancellationToken.ThrowIfCancellationRequested();
@ -281,7 +281,7 @@ public sealed class OpenIddictValidationService
{
var context = new PrepareCryptographyRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request
};
@ -301,7 +301,7 @@ public sealed class OpenIddictValidationService
{
var context = new ApplyCryptographyRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request
};
@ -314,7 +314,7 @@ public sealed class OpenIddictValidationService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6188), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6188), context.RemoteUri, context.Request);
return context.Request;
}
@ -323,7 +323,7 @@ public sealed class OpenIddictValidationService
{
var context = new ExtractCryptographyResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Request = request
};
@ -338,7 +338,7 @@ public sealed class OpenIddictValidationService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6189), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6189), context.RemoteUri, context.Response);
return context.Response;
}
@ -379,24 +379,24 @@ public sealed class OpenIddictValidationService
}
/// <summary>
/// Sends an introspection request to the specified address and returns the corresponding principal.
/// Sends an introspection request to the specified URI and returns the corresponding principal.
/// </summary>
/// <param name="address">The address of the remote metadata endpoint.</param>
/// <param name="uri">The URI of the remote metadata endpoint.</param>
/// <param name="token">The token to introspect.</param>
/// <param name="hint">The token type to introspect, used as a hint by the authorization server.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The claims principal created from the claim retrieved from the remote server.</returns>
internal async ValueTask<ClaimsPrincipal> IntrospectTokenAsync(
Uri address, string token, string? hint, CancellationToken cancellationToken = default)
Uri uri, string token, string? hint, CancellationToken cancellationToken = default)
{
if (address is null)
if (uri is null)
{
throw new ArgumentNullException(nameof(address));
throw new ArgumentNullException(nameof(uri));
}
if (!address.IsAbsoluteUri || !address.IsWellFormedOriginalString())
if (!uri.IsAbsoluteUri || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(address));
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
if (string.IsNullOrEmpty(token))
@ -435,7 +435,7 @@ public sealed class OpenIddictValidationService
{
var context = new PrepareIntrospectionRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Request = request,
Token = token,
@ -458,7 +458,7 @@ public sealed class OpenIddictValidationService
{
var context = new ApplyIntrospectionRequestContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Request = request
};
@ -472,7 +472,7 @@ public sealed class OpenIddictValidationService
context.Error, context.ErrorDescription, context.ErrorUri);
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID6190), context.Address, context.Request);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6190), context.RemoteUri, context.Request);
return context.Request;
}
@ -481,7 +481,7 @@ public sealed class OpenIddictValidationService
{
var context = new ExtractIntrospectionResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Request = request
};
@ -497,7 +497,7 @@ public sealed class OpenIddictValidationService
Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007));
context.Logger.LogInformation(SR.GetResourceString(SR.ID6191), context.Address, context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID6191), context.RemoteUri, context.Response);
return context.Response;
}
@ -506,7 +506,7 @@ public sealed class OpenIddictValidationService
{
var context = new HandleIntrospectionResponseContext(transaction)
{
Address = address,
RemoteUri = uri,
Configuration = configuration,
Request = request,
Response = response,

12
test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs

@ -269,7 +269,7 @@ public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServ
[InlineData("/connect/token")]
[InlineData("/connect/userinfo")]
[InlineData("/connect/verification")]
public async Task ProcessRequest_RejectsInsecureHttpRequests(string address)
public async Task ProcessRequest_RejectsInsecureHttpRequests(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -283,7 +283,7 @@ public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServ
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync(address, new OpenIddictRequest());
var response = await client.PostAsync(uri, new OpenIddictRequest());
// Assert
Assert.Equal(Errors.InvalidRequest, response.Error);
@ -303,7 +303,7 @@ public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServ
[InlineData("/connect/token")]
[InlineData("/connect/userinfo")]
[InlineData("/connect/verification")]
public async Task ProcessRequest_AllowsHandlingResponse(string address)
public async Task ProcessRequest_AllowsHandlingResponse(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -327,7 +327,7 @@ public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServ
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync(address, new OpenIddictRequest());
var response = await client.PostAsync(uri, new OpenIddictRequest());
// Assert
Assert.Equal("Bob le Bricoleur", (string?) response["name"]);
@ -345,7 +345,7 @@ public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServ
[InlineData("/connect/token")]
[InlineData("/connect/userinfo")]
[InlineData("/connect/verification")]
public async Task ProcessRequest_AllowsSkippingHandler(string address)
public async Task ProcessRequest_AllowsSkippingHandler(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -364,7 +364,7 @@ public partial class OpenIddictServerAspNetCoreIntegrationTests : OpenIddictServ
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync(address, new OpenIddictRequest());
var response = await client.PostAsync(uri, new OpenIddictRequest());
// Assert
Assert.Equal("Bob le Magnifique", (string?) response["name"]);

10
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs

@ -91,7 +91,7 @@ public class OpenIddictServerIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return GetAsync(new Uri(uri, UriKind.RelativeOrAbsolute), request);
@ -123,7 +123,7 @@ public class OpenIddictServerIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return PostAsync(new Uri(uri, UriKind.RelativeOrAbsolute), request);
@ -161,7 +161,7 @@ public class OpenIddictServerIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return SendAsync(new HttpMethod(method), uri, request);
@ -189,7 +189,7 @@ public class OpenIddictServerIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return SendAsync(method, new Uri(uri, UriKind.RelativeOrAbsolute), request);
@ -222,7 +222,7 @@ public class OpenIddictServerIntegrationTestClient : IAsyncDisposable
if (HttpClient.BaseAddress is null && !uri.IsAbsoluteUri)
{
throw new ArgumentException("The address cannot be a relative URI when no base address " +
throw new ArgumentException("The URI cannot be a relative URI when no base URI " +
"is associated with the HTTP client.", nameof(uri));
}

8
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs

@ -222,7 +222,7 @@ public abstract partial class OpenIddictServerIntegrationTests
[InlineData("/tmp/file.xml", SR.ID2030)]
[InlineData("C:\\tmp\\file.xml", SR.ID2030)]
[InlineData("http://www.fabrikam.com/path#param=value", SR.ID2031)]
public async Task ValidateAuthorizationRequest_InvalidRedirectUriCausesAnError(string address, string message)
public async Task ValidateAuthorizationRequest_InvalidRedirectUriCausesAnError(string uri, string message)
{
// Arrange
await using var server = await CreateServerAsync(options => options.EnableDegradedMode());
@ -232,7 +232,7 @@ public abstract partial class OpenIddictServerIntegrationTests
var response = await client.PostAsync("/connect/authorize", new OpenIddictRequest
{
ClientId = "Fabrikam",
RedirectUri = address,
RedirectUri = uri,
Scope = Scopes.OpenId
});
@ -257,7 +257,7 @@ public abstract partial class OpenIddictServerIntegrationTests
[InlineData("http://www.fabrikam.com/path?state=abc;iss=value")]
[InlineData("http://www.fabrikam.com/path?state=abc&iss")]
[InlineData("http://www.fabrikam.com/path?state=abc&iss=value")]
public async Task ValidateAuthorizationRequest_RedirectUriWithIssuerParameterCausesAnError(string address)
public async Task ValidateAuthorizationRequest_RedirectUriWithIssuerParameterCausesAnError(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options => options.EnableDegradedMode());
@ -267,7 +267,7 @@ public abstract partial class OpenIddictServerIntegrationTests
var response = await client.PostAsync("/connect/authorize", new OpenIddictRequest
{
ClientId = "Fabrikam",
RedirectUri = address,
RedirectUri = uri,
Scope = Scopes.OpenId
});

4
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Session.cs

@ -134,7 +134,7 @@ public abstract partial class OpenIddictServerIntegrationTests
[InlineData("/tmp/file.xml", SR.ID2030)]
[InlineData("C:\\tmp\\file.xml", SR.ID2030)]
[InlineData("http://www.fabrikam.com/path#param=value", SR.ID2031)]
public async Task ValidateLogoutRequest_InvalidRedirectUriCausesAnError(string address, string message)
public async Task ValidateLogoutRequest_InvalidRedirectUriCausesAnError(string uri, string message)
{
// Arrange
await using var server = await CreateServerAsync();
@ -143,7 +143,7 @@ public abstract partial class OpenIddictServerIntegrationTests
// Act
var response = await client.PostAsync("/connect/logout", new OpenIddictRequest
{
PostLogoutRedirectUri = address
PostLogoutRedirectUri = uri
});
// Assert

4
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

@ -391,7 +391,7 @@ public abstract partial class OpenIddictServerIntegrationTests
[InlineData("/custom/connect/token", OpenIddictServerEndpointType.Token)]
[InlineData("/custom/connect/userinfo", OpenIddictServerEndpointType.Userinfo)]
[InlineData("/custom/connect/verification", OpenIddictServerEndpointType.Verification)]
public async Task ProcessRequest_AllowsOverridingEndpoint(string address, OpenIddictServerEndpointType type)
public async Task ProcessRequest_AllowsOverridingEndpoint(string uri, OpenIddictServerEndpointType type)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -434,7 +434,7 @@ public abstract partial class OpenIddictServerIntegrationTests
await using var client = await server.CreateClientAsync();
// Act
await client.PostAsync(address, new OpenIddictRequest());
await client.PostAsync(uri, new OpenIddictRequest());
}
[Fact]

12
test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs

@ -254,7 +254,7 @@ public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerInte
[InlineData("/connect/token")]
[InlineData("/connect/userinfo")]
[InlineData("/connect/verification")]
public async Task ProcessRequest_RejectsInsecureHttpRequests(string address)
public async Task ProcessRequest_RejectsInsecureHttpRequests(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -268,7 +268,7 @@ public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerInte
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync(address, new OpenIddictRequest());
var response = await client.PostAsync(uri, new OpenIddictRequest());
// Assert
Assert.Equal(Errors.InvalidRequest, response.Error);
@ -288,7 +288,7 @@ public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerInte
[InlineData("/connect/token")]
[InlineData("/connect/userinfo")]
[InlineData("/connect/verification")]
public async Task ProcessRequest_AllowsHandlingResponse(string address)
public async Task ProcessRequest_AllowsHandlingResponse(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -312,7 +312,7 @@ public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerInte
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync(address, new OpenIddictRequest());
var response = await client.PostAsync(uri, new OpenIddictRequest());
// Assert
Assert.Equal("Bob le Bricoleur", (string?) response["name"]);
@ -330,7 +330,7 @@ public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerInte
[InlineData("/connect/token")]
[InlineData("/connect/userinfo")]
[InlineData("/connect/verification")]
public async Task ProcessRequest_AllowsSkippingHandler(string address)
public async Task ProcessRequest_AllowsSkippingHandler(string uri)
{
// Arrange
await using var server = await CreateServerAsync(options =>
@ -349,7 +349,7 @@ public partial class OpenIddictServerOwinIntegrationTests : OpenIddictServerInte
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync(address, new OpenIddictRequest());
var response = await client.PostAsync(uri, new OpenIddictRequest());
// Assert
Assert.Equal("Bob le Magnifique", (string?) response["name"]);

164
test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

@ -753,27 +753,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetAuthorizationEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetAuthorizationEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetAuthorizationEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetAuthorizationEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetAuthorizationEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetAuthorizationEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetAuthorizationEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetAuthorizationEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -786,7 +786,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetAuthorizationEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -800,7 +800,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetAuthorizationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -837,27 +837,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetConfigurationEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetConfigurationEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetConfigurationEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetConfigurationEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetConfigurationEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetConfigurationEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetConfigurationEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetConfigurationEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -870,7 +870,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetConfigurationEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -884,7 +884,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetConfigurationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -921,27 +921,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetCryptographyEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetCryptographyEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetCryptographyEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetCryptographyEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetCryptographyEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetCryptographyEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetCryptographyEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetCryptographyEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -954,7 +954,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetCryptographyEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -968,7 +968,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetCryptographyEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1005,27 +1005,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetDeviceEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetDeviceEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetDeviceEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetDeviceEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetDeviceEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetDeviceEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetDeviceEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetDeviceEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1038,7 +1038,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetDeviceEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1052,7 +1052,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetDeviceEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1089,27 +1089,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetIntrospectionEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetIntrospectionEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIntrospectionEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIntrospectionEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetIntrospectionEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetIntrospectionEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIntrospectionEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIntrospectionEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1122,7 +1122,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetIntrospectionEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1136,7 +1136,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetIntrospectionEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1173,27 +1173,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetLogoutEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetLogoutEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetLogoutEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetLogoutEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetLogoutEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetLogoutEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetLogoutEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetLogoutEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1206,7 +1206,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetLogoutEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1220,7 +1220,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetLogoutEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1257,27 +1257,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetRevocationEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetRevocationEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetRevocationEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetRevocationEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetRevocationEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetRevocationEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetRevocationEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetRevocationEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1290,7 +1290,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetRevocationEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1304,7 +1304,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetRevocationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1341,27 +1341,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetTokenEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetTokenEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetTokenEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetTokenEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetTokenEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetTokenEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetTokenEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetTokenEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1374,7 +1374,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetTokenEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1388,7 +1388,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetTokenEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1425,27 +1425,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetUserinfoEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetUserinfoEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetUserinfoEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetUserinfoEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetUserinfoEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetUserinfoEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetUserinfoEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetUserinfoEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1458,7 +1458,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetUserinfoEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1472,7 +1472,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetUserinfoEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1509,27 +1509,27 @@ public class OpenIddictServerBuilderTests
}
[Fact]
public void SetVerificationEndpointUris_ThrowsExceptionWhenAddressesIsNull()
public void SetVerificationEndpointUris_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetVerificationEndpointUris(addresses: (null as Uri[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetVerificationEndpointUris(uris: (null as Uri[])!));
Assert.Equal("uris", exception.ParamName);
}
[Fact]
public void SetVerificationEndpointUris_Strings_ThrowsExceptionWhenAddressesIsNull()
public void SetVerificationEndpointUris_Strings_ThrowsExceptionWhenUrisIsNull()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetVerificationEndpointUris(addresses: (null as string[])!));
Assert.Equal("addresses", exception.ParamName);
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetVerificationEndpointUris(uris: (null as string[])!));
Assert.Equal("uris", exception.ParamName);
}
[Theory]
@ -1542,7 +1542,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetVerificationEndpointUris(new Uri(uri)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message);
}
@ -1556,7 +1556,7 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetVerificationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute)));
Assert.Equal("addresses", exception.ParamName);
Assert.Equal("uris", exception.ParamName);
Assert.Contains(SR.FormatID0081("~"), exception.Message);
}
@ -1810,11 +1810,11 @@ public class OpenIddictServerBuilderTests
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIssuer(null!));
Assert.Equal("address", exception.ParamName);
Assert.Equal("uri", exception.ParamName);
}
[Fact]
public void SetIssuer_AddressIsReplaced()
public void SetIssuer_IssuerIsReplaced()
{
// Arrange
var services = CreateServices();

10
test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTestClient.cs

@ -91,7 +91,7 @@ public class OpenIddictValidationIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return GetAsync(new Uri(uri, UriKind.RelativeOrAbsolute), request);
@ -123,7 +123,7 @@ public class OpenIddictValidationIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return PostAsync(new Uri(uri, UriKind.RelativeOrAbsolute), request);
@ -161,7 +161,7 @@ public class OpenIddictValidationIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return SendAsync(new HttpMethod(method), uri, request);
@ -189,7 +189,7 @@ public class OpenIddictValidationIntegrationTestClient : IAsyncDisposable
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException("The URL cannot be null or empty.", nameof(uri));
throw new ArgumentException("The URI cannot be null or empty.", nameof(uri));
}
return SendAsync(method, new Uri(uri, UriKind.RelativeOrAbsolute), request);
@ -222,7 +222,7 @@ public class OpenIddictValidationIntegrationTestClient : IAsyncDisposable
if (HttpClient.BaseAddress is null && !uri.IsAbsoluteUri)
{
throw new ArgumentException("The address cannot be a relative URI when no base address " +
throw new ArgumentException("The URI cannot be a relative URI when no base URI " +
"is associated with the HTTP client.", nameof(uri));
}

Loading…
Cancel
Save