Browse Source

Update OpenIddictValidationServerIntegrationConfiguration to initialize OpenIddictValidationOptions.Issuer and add new SetClientUri/SetIssuer overloads

=
pull/1741/head
Kévin Chalet 3 years ago
parent
commit
233c76b08e
  1. 6
      src/OpenIddict.Abstractions/OpenIddictResources.resx
  2. 2
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpBuilder.cs
  3. 21
      src/OpenIddict.Client/OpenIddictClientBuilder.cs
  4. 8
      src/OpenIddict.Client/OpenIddictClientConfiguration.cs
  5. 2
      src/OpenIddict.Client/OpenIddictClientHandlers.cs
  6. 21
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  7. 2
      src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
  8. 3
      src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs
  9. 2
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpBuilder.cs
  10. 10
      src/OpenIddict.Validation/OpenIddictValidationConfiguration.cs
  11. 20
      test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

6
src/OpenIddict.Abstractions/OpenIddictResources.resx

@ -1480,6 +1480,12 @@ To apply post-logout redirection responses, create a class implementing 'IOpenId
<data name="ID0393" xml:space="preserve">
<value>The web authentication result cannot be resolved or contains invalid data.</value>
</data>
<data name="ID0394" xml:space="preserve">
<value>The issuer attached to the static configuration must be the same as the one configured in the validation options.</value>
</data>
<data name="ID0395" xml:space="preserve">
<value>The issuer attached to the static configuration must be the same as the one configured in the client registration.</value>
</data>
<data name="ID2000" xml:space="preserve">
<value>The security token is missing.</value>
</data>

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

@ -75,7 +75,7 @@ public sealed class OpenIddictClientSystemNetHttpBuilder
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0366), nameof(address));
throw new ArgumentException(SR.FormatID0366(nameof(address)), nameof(address));
}
return SetContactAddress(new MailAddress(address));

21
src/OpenIddict.Client/OpenIddictClientBuilder.cs

@ -1141,6 +1141,27 @@ public sealed class OpenIddictClientBuilder
return Configure(options => options.ClientUri = uri);
}
/// <summary>
/// Sets the client URI, which is used as the value of the "issuer" claim.
/// </summary>
/// <param name="uri">The client URI.</param>
/// <returns>The <see cref="OpenIddictClientBuilder"/> instance.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictClientBuilder SetClientUri([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.FormatID0366(nameof(uri)), nameof(uri));
}
if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? value) || !value.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
return SetClientUri(value);
}
/// <inheritdoc/>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object? obj) => base.Equals(obj);

8
src/OpenIddict.Client/OpenIddictClientConfiguration.cs

@ -57,7 +57,13 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions<OpenId
{
if (registration.Configuration is not null)
{
registration.Configuration.Issuer = registration.Issuer;
if (registration.Configuration.Issuer is not null &&
registration.Configuration.Issuer != registration.Issuer)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0395));
}
registration.Configuration.Issuer ??= registration.Issuer;
registration.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(registration.Configuration);
}

2
src/OpenIddict.Client/OpenIddictClientHandlers.cs

@ -4483,7 +4483,7 @@ public static partial class OpenIddictClientHandlers
// If the request is an OpenID Connect request, the nonce will also be hashed and
// attached to the authorization request so that the identity provider can bind
// the issued identity tokens to the generated value, which helps detect token
// replay (and authorization code injection attacks when PKCE is not available).
// replays (and authorization code injection attacks when PKCE is not available).
context.Nonce = Base64UrlEncoder.Encode(OpenIddictHelpers.CreateRandomArray(size: 256));
return default;

21
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -1731,6 +1731,27 @@ public sealed class OpenIddictServerBuilder
return Configure(options => options.Issuer = uri);
}
/// <summary>
/// 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="uri">The issuer uri.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/> instance.</returns>
public OpenIddictServerBuilder SetIssuer([StringSyntax(StringSyntaxAttribute.Uri)] string uri)
{
if (string.IsNullOrEmpty(uri))
{
throw new ArgumentException(SR.FormatID0366(nameof(uri)), nameof(uri));
}
if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? value) || !value.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID0144), nameof(uri));
}
return SetIssuer(value);
}
/// <summary>
/// Configures OpenIddict to use reference tokens, so that the access token payloads
/// are stored in the database (only an identifier is returned to the client application).

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

@ -1559,7 +1559,7 @@ public static partial class OpenIddictServerHandlers
if (string.IsNullOrEmpty(challenge))
{
// Validate that the token request does not include a code_verifier parameter
// when code_challenge private claim was attached to the authorization code.
// when no code_challenge private claim was attached to the authorization code.
if (!string.IsNullOrEmpty(context.Request.CodeVerifier))
{
context.Logger.LogInformation(SR.GetResourceString(SR.ID6093), Parameters.CodeVerifier);

3
src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs

@ -36,9 +36,10 @@ public sealed class OpenIddictValidationServerIntegrationConfiguration : IConfig
// Note: the issuer may be null. In this case, it will be usually provided by
// a validation handler registered by the host (e.g ASP.NET Core or OWIN/Katana).
options.Issuer = _options.CurrentValue.Issuer;
options.Configuration = new OpenIddictConfiguration
{
Issuer = _options.CurrentValue.Issuer
Issuer = options.Issuer
};
// Import the signing keys from the server configuration.

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

@ -75,7 +75,7 @@ public sealed class OpenIddictValidationSystemNetHttpBuilder
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException(SR.GetResourceString(SR.ID0366), nameof(address));
throw new ArgumentException(SR.FormatID0366(nameof(address)), nameof(address));
}
return SetContactAddress(new MailAddress(address));

10
src/OpenIddict.Validation/OpenIddictValidationConfiguration.cs

@ -95,7 +95,15 @@ public sealed class OpenIddictValidationConfiguration : IPostConfigureOptions<Op
{
if (options.Configuration is not null)
{
options.Configuration.Issuer = options.Issuer;
if (options.Configuration.Issuer is not null &&
options.Configuration.Issuer != options.Issuer)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0394));
}
// Note: the issuer may be null. In this case, it will be usually provided by
// a validation handler registered by the host (e.g ASP.NET Core or OWIN/Katana).
options.Configuration.Issuer ??= options.Issuer;
options.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(options.Configuration);
}

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

@ -1808,11 +1808,27 @@ public class OpenIddictServerBuilderTests
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIssuer(null!));
var exception = Assert.Throws<ArgumentNullException>(() => builder.SetIssuer((Uri?) null!));
Assert.Equal("uri", exception.ParamName);
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void SetIssuer_ThrowsAnExceptionForNullOrEmptyIssuer(string? uri)
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetIssuer(uri!));
Assert.Equal("uri", exception.ParamName);
Assert.StartsWith(SR.FormatID0366("uri"), exception.Message);
}
[Fact]
public void SetIssuer_IssuerIsReplaced()
{
@ -1821,7 +1837,7 @@ public class OpenIddictServerBuilderTests
var builder = CreateBuilder(services);
// Act
builder.SetIssuer(new Uri("http://www.fabrikam.com/"));
builder.SetIssuer("http://www.fabrikam.com/");
var options = GetOptions(services);

Loading…
Cancel
Save