Browse Source

Add nullable annotations to OpenIddict.Validation, OpenIddict.Validation.AspNetCore, OpenIddict.Validation.Owin, OpenIddict.Validation.ServerIntegration, OpenIddict.Validation.SystemNetHttp and OpenIddict.Validation.DataProtection

pull/1038/head
Kévin Chalet 6 years ago
parent
commit
3df97d59e6
  1. 5
      src/OpenIddict.Validation.AspNetCore/OpenIddict.Validation.AspNetCore.csproj
  2. 11
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreBuilder.cs
  3. 23
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreConfiguration.cs
  4. 6
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreExtensions.cs
  5. 2
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreFeature.cs
  6. 38
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
  7. 3
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlerFilters.cs
  8. 128
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs
  9. 13
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHelpers.cs
  10. 5
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreOptions.cs
  11. 3
      src/OpenIddict.Validation.DataProtection/IOpenIddictValidationDataProtectionFormatter.cs
  12. 5
      src/OpenIddict.Validation.DataProtection/OpenIddict.Validation.DataProtection.csproj
  13. 13
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionBuilder.cs
  14. 7
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConfiguration.cs
  15. 6
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionExtensions.cs
  16. 7
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs
  17. 13
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs
  18. 2
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionOptions.cs
  19. 1
      src/OpenIddict.Validation.Owin/OpenIddict.Validation.Owin.csproj
  20. 11
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinBuilder.cs
  21. 3
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinConfiguration.cs
  22. 6
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinExtensions.cs
  23. 34
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
  24. 3
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlerFilters.cs
  25. 134
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs
  26. 15
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHelpers.cs
  27. 9
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinMiddleware.cs
  28. 5
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinMiddlewareFactory.cs
  29. 5
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinOptions.cs
  30. 1
      src/OpenIddict.Validation.ServerIntegration/OpenIddict.Validation.ServerIntegration.csproj
  31. 9
      src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationBuilder.cs
  32. 7
      src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs
  33. 6
      src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationExtensions.cs
  34. 1
      src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj
  35. 11
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpBuilder.cs
  36. 13
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpConfiguration.cs
  37. 6
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpExtensions.cs
  38. 3
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlerFilters.cs
  39. 9
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs
  40. 42
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
  41. 9
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHelpers.cs
  42. 2
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpOptions.cs
  43. 3
      src/OpenIddict.Validation/IOpenIddictValidationDispatcher.cs
  44. 3
      src/OpenIddict.Validation/IOpenIddictValidationHandler.cs
  45. 3
      src/OpenIddict.Validation/IOpenIddictValidationHandlerFilter.cs
  46. 1
      src/OpenIddict.Validation/OpenIddict.Validation.csproj
  47. 49
      src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
  48. 72
      src/OpenIddict.Validation/OpenIddictValidationConfiguration.cs
  49. 9
      src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
  50. 126
      src/OpenIddict.Validation/OpenIddictValidationEvents.Discovery.cs
  51. 74
      src/OpenIddict.Validation/OpenIddictValidationEvents.Introspection.cs
  52. 102
      src/OpenIddict.Validation/OpenIddictValidationEvents.cs
  53. 7
      src/OpenIddict.Validation/OpenIddictValidationExtensions.cs
  54. 7
      src/OpenIddict.Validation/OpenIddictValidationFactory.cs
  55. 5
      src/OpenIddict.Validation/OpenIddictValidationHandler.cs
  56. 15
      src/OpenIddict.Validation/OpenIddictValidationHandlerDescriptor.cs
  57. 9
      src/OpenIddict.Validation/OpenIddictValidationHandlerFilters.cs
  58. 73
      src/OpenIddict.Validation/OpenIddictValidationHandlers.Discovery.cs
  59. 79
      src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs
  60. 151
      src/OpenIddict.Validation/OpenIddictValidationHandlers.cs
  61. 9
      src/OpenIddict.Validation/OpenIddictValidationHelpers.cs
  62. 12
      src/OpenIddict.Validation/OpenIddictValidationOptions.cs
  63. 5
      src/OpenIddict.Validation/OpenIddictValidationRetriever.cs
  64. 29
      src/OpenIddict.Validation/OpenIddictValidationService.cs
  65. 16
      src/OpenIddict.Validation/OpenIddictValidationTransaction.cs

5
src/OpenIddict.Validation.AspNetCore/OpenIddict.Validation.AspNetCore.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
@ -14,12 +15,12 @@
</ItemGroup>
<ItemGroup
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.1')) ">
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.0')) ">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup
Condition=" '$(TargetFrameworkIdentifier)' != '.NETCoreApp' Or $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.1')) ">
Condition=" '$(TargetFrameworkIdentifier)' != '.NETCoreApp' Or $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0')) ">
<PackageReference Include="Microsoft.AspNetCore.Authentication" />
</ItemGroup>

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

@ -6,7 +6,6 @@
using System;
using System.ComponentModel;
using JetBrains.Annotations;
using OpenIddict.Validation.AspNetCore;
using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -22,7 +21,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictValidationAspNetCoreBuilder"/>.
/// </summary>
/// <param name="services">The services collection.</param>
public OpenIddictValidationAspNetCoreBuilder([NotNull] IServiceCollection services)
public OpenIddictValidationAspNetCoreBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary>
@ -37,7 +36,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationAspNetCoreBuilder"/>.</returns>
public OpenIddictValidationAspNetCoreBuilder Configure([NotNull] Action<OpenIddictValidationAspNetCoreOptions> configuration)
public OpenIddictValidationAspNetCoreBuilder Configure(Action<OpenIddictValidationAspNetCoreOptions> configuration)
{
if (configuration == null)
{
@ -54,7 +53,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="realm">The issuer address.</param>
/// <returns>The <see cref="OpenIddictValidationAspNetCoreBuilder"/>.</returns>
public OpenIddictValidationAspNetCoreBuilder SetRealm([NotNull] string realm)
public OpenIddictValidationAspNetCoreBuilder SetRealm(string realm)
{
if (string.IsNullOrEmpty(realm))
{
@ -70,7 +69,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj);
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
@ -84,6 +83,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string? ToString() => base.ToString();
}
}

23
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreConfiguration.cs

@ -5,7 +5,7 @@
*/
using System;
using JetBrains.Annotations;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -23,7 +23,7 @@ namespace OpenIddict.Validation.AspNetCore
/// Registers the OpenIddict validation handler in the global authentication options.
/// </summary>
/// <param name="options">The options instance to initialize.</param>
public void Configure([NotNull] AuthenticationOptions options)
public void Configure(AuthenticationOptions options)
{
if (options == null)
{
@ -41,7 +41,7 @@ namespace OpenIddict.Validation.AspNetCore
OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme, displayName: null);
}
public void Configure([NotNull] OpenIddictValidationOptions options)
public void Configure(OpenIddictValidationOptions options)
{
if (options == null)
{
@ -57,28 +57,29 @@ namespace OpenIddict.Validation.AspNetCore
/// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] AuthenticationOptions options)
public void PostConfigure(string name, AuthenticationOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
bool TryValidate(string scheme)
if (!TryValidate(options.SchemeMap, options.DefaultSignInScheme) ||
!TryValidate(options.SchemeMap, options.DefaultSignOutScheme))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1164));
}
static bool TryValidate(IDictionary<string, AuthenticationSchemeBuilder> map, string? scheme)
{
// If the scheme was not set or if it cannot be found in the map, return true.
if (string.IsNullOrEmpty(scheme) || !options.SchemeMap.TryGetValue(scheme, out var builder))
if (string.IsNullOrEmpty(scheme) || !map.TryGetValue(scheme, out var builder))
{
return true;
}
return builder.HandlerType != typeof(OpenIddictValidationAspNetCoreHandler);
}
if (!TryValidate(options.DefaultSignInScheme) || !TryValidate(options.DefaultSignOutScheme))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1164));
}
}
}
}

6
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreExtensions.cs

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
@ -28,7 +27,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationAspNetCoreBuilder"/>.</returns>
public static OpenIddictValidationAspNetCoreBuilder UseAspNetCore([NotNull] this OpenIddictValidationBuilder builder)
public static OpenIddictValidationAspNetCoreBuilder UseAspNetCore(this OpenIddictValidationBuilder builder)
{
if (builder == null)
{
@ -67,8 +66,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationBuilder UseAspNetCore(
[NotNull] this OpenIddictValidationBuilder builder,
[NotNull] Action<OpenIddictValidationAspNetCoreBuilder> configuration)
this OpenIddictValidationBuilder builder, Action<OpenIddictValidationAspNetCoreBuilder> configuration)
{
if (builder == null)
{

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

@ -15,6 +15,6 @@ namespace OpenIddict.Validation.AspNetCore
/// Gets or sets the validation transaction that encapsulates all specific
/// information about an individual OpenID Connect validation request.
/// </summary>
public OpenIddictValidationTransaction Transaction { get; set; }
public OpenIddictValidationTransaction? Transaction { get; set; }
}
}

38
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs

@ -6,9 +6,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@ -33,18 +33,19 @@ namespace OpenIddict.Validation.AspNetCore
/// Creates a new instance of the <see cref="OpenIddictValidationAspNetCoreHandler"/> class.
/// </summary>
public OpenIddictValidationAspNetCoreHandler(
[NotNull] IOpenIddictValidationDispatcher dispatcher,
[NotNull] IOpenIddictValidationFactory factory,
[NotNull] IOptionsMonitor<OpenIddictValidationAspNetCoreOptions> options,
[NotNull] ILoggerFactory logger,
[NotNull] UrlEncoder encoder,
[NotNull] ISystemClock clock)
IOpenIddictValidationDispatcher dispatcher,
IOpenIddictValidationFactory factory,
IOptionsMonitor<OpenIddictValidationAspNetCoreOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
_dispatcher = dispatcher;
_factory = factory;
}
/// <inheritdoc/>
public async Task<bool> HandleRequestAsync()
{
// Note: the transaction may be already attached when replaying an ASP.NET Core request
@ -54,7 +55,7 @@ namespace OpenIddict.Validation.AspNetCore
{
// Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers.
transaction = await _factory.CreateTransactionAsync();
transaction.Properties[typeof(HttpRequest).FullName] = new WeakReference<HttpRequest>(Request);
transaction.Properties[typeof(HttpRequest).FullName!] = new WeakReference<HttpRequest>(Request);
// Attach the OpenIddict validation transaction to the ASP.NET Core features
// so that it can retrieved while performing challenge/forbid operations.
@ -104,6 +105,7 @@ namespace OpenIddict.Validation.AspNetCore
return false;
}
/// <inheritdoc/>
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
var transaction = Context.Features.Get<OpenIddictValidationAspNetCoreFeature>()?.Transaction ??
@ -112,7 +114,7 @@ namespace OpenIddict.Validation.AspNetCore
// Note: in many cases, the authentication token was already validated by the time this action is called
// (generally later in the pipeline, when using the pass-through mode). To avoid having to re-validate it,
// the authentication context is resolved from the transaction. If it's not available, a new one is created.
var context = transaction.GetProperty<ProcessAuthenticationContext>(typeof(ProcessAuthenticationContext).FullName);
var context = transaction.GetProperty<ProcessAuthenticationContext>(typeof(ProcessAuthenticationContext).FullName!);
if (context == null)
{
context = new ProcessAuthenticationContext(transaction);
@ -120,7 +122,7 @@ namespace OpenIddict.Validation.AspNetCore
// Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the authentication result without triggering a new authentication flow.
transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName, context);
transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName!, context);
}
if (context.IsRequestHandled || context.IsRequestSkipped)
@ -138,7 +140,7 @@ namespace OpenIddict.Validation.AspNetCore
return AuthenticateResult.NoResult();
}
var properties = new AuthenticationProperties(new Dictionary<string, string>
var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[OpenIddictValidationAspNetCoreConstants.Properties.Error] = context.Error,
[OpenIddictValidationAspNetCoreConstants.Properties.ErrorDescription] = context.ErrorDescription,
@ -150,6 +152,10 @@ namespace OpenIddict.Validation.AspNetCore
else
{
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
Debug.Assert(!string.IsNullOrEmpty(context.Principal.GetTokenType()), SR.GetResourceString(SR.ID5009));
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID5010));
// Store the token to allow any ASP.NET Core component (e.g a controller)
// to retrieve it (e.g to make an API request to another application).
var properties = new AuthenticationProperties();
@ -157,7 +163,7 @@ namespace OpenIddict.Validation.AspNetCore
{
new AuthenticationToken
{
Name = context.TokenType,
Name = context.Principal.GetTokenType(),
Value = context.Token
}
});
@ -168,12 +174,13 @@ namespace OpenIddict.Validation.AspNetCore
}
}
protected override async Task HandleChallengeAsync([CanBeNull] AuthenticationProperties properties)
/// <inheritdoc/>
protected override async Task HandleChallengeAsync(AuthenticationProperties? properties)
{
var transaction = Context.Features.Get<OpenIddictValidationAspNetCoreFeature>()?.Transaction ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1165));
transaction.Properties[typeof(AuthenticationProperties).FullName] = properties ?? new AuthenticationProperties();
transaction.Properties[typeof(AuthenticationProperties).FullName!] = properties ?? new AuthenticationProperties();
var context = new ProcessChallengeContext(transaction)
{
@ -210,7 +217,8 @@ namespace OpenIddict.Validation.AspNetCore
}
}
protected override Task HandleForbiddenAsync([CanBeNull] AuthenticationProperties properties)
/// <inheritdoc/>
protected override Task HandleForbiddenAsync(AuthenticationProperties? properties)
=> HandleChallengeAsync(properties);
}
}

3
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlerFilters.cs

@ -7,7 +7,6 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore;
using static OpenIddict.Validation.OpenIddictValidationEvents;
@ -24,7 +23,7 @@ namespace OpenIddict.Validation.AspNetCore
/// </summary>
public class RequireHttpRequest : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{

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

@ -8,12 +8,12 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
@ -82,14 +82,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -120,7 +114,7 @@ namespace OpenIddict.Validation.AspNetCore
return default;
}
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer) ||
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) ||
!issuer.IsWellFormedOriginalString())
{
context.Reject(
@ -153,14 +147,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -213,14 +201,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -277,14 +259,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -336,21 +312,15 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessChallengeContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName);
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties != null)
{
context.Response.Error = properties.GetString(Properties.Error);
@ -380,20 +350,16 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
@ -402,7 +368,7 @@ namespace OpenIddict.Validation.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
}
response.StatusCode = context.Response.Error switch
response.StatusCode = context.Transaction.Response.Error switch
{
null => 200,
@ -436,14 +402,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -475,7 +435,7 @@ namespace OpenIddict.Validation.AspNetCore
{
private readonly IOptionsMonitor<OpenIddictValidationAspNetCoreOptions> _options;
public AttachWwwAuthenticateHeader([NotNull] IOptionsMonitor<OpenIddictValidationAspNetCoreOptions> options)
public AttachWwwAuthenticateHeader(IOptionsMonitor<OpenIddictValidationAspNetCoreOptions> options)
=> _options = options;
/// <summary>
@ -489,20 +449,16 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
@ -511,7 +467,7 @@ namespace OpenIddict.Validation.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
}
var scheme = context.Response.Error switch
var scheme = context.Transaction.Response.Error switch
{
Errors.InvalidToken => Schemes.Bearer,
Errors.MissingToken => Schemes.Bearer,
@ -534,11 +490,11 @@ namespace OpenIddict.Validation.AspNetCore
parameters[Parameters.Realm] = _options.CurrentValue.Realm;
}
foreach (var parameter in context.Response.GetParameters())
foreach (var parameter in context.Transaction.Response.GetParameters())
{
// Note: the error details are only included if the error was not caused by a missing token, as recommended
// by the OAuth 2.0 bearer specification: https://tools.ietf.org/html/rfc6750#section-3.1.
if (string.Equals(context.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
if (string.Equals(context.Transaction.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
(string.Equals(parameter.Key, Parameters.Error, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal)))
@ -547,7 +503,7 @@ namespace OpenIddict.Validation.AspNetCore
}
// Ignore values that can't be represented as unique strings.
var value = (string) parameter.Value;
var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value))
{
continue;
@ -598,14 +554,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -626,7 +576,7 @@ namespace OpenIddict.Validation.AspNetCore
return default;
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Transaction.Response);
context.HandleRequest();
return default;
@ -650,14 +600,8 @@ namespace OpenIddict.Validation.AspNetCore
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -672,10 +616,10 @@ namespace OpenIddict.Validation.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Response, new JsonSerializerOptions
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false

13
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHelpers.cs

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using OpenIddict.Abstractions;
using OpenIddict.Validation;
@ -24,19 +23,19 @@ namespace Microsoft.AspNetCore
/// </summary>
/// <param name="transaction">The transaction instance.</param>
/// <returns>The <see cref="HttpRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static HttpRequest GetHttpRequest([NotNull] this OpenIddictValidationTransaction transaction)
public static HttpRequest? GetHttpRequest(this OpenIddictValidationTransaction transaction)
{
if (transaction == null)
{
throw new ArgumentNullException(nameof(transaction));
}
if (!transaction.Properties.TryGetValue(typeof(HttpRequest).FullName, out object property))
if (!transaction.Properties.TryGetValue(typeof(HttpRequest).FullName!, out object? property))
{
return null;
}
if (property is WeakReference<HttpRequest> reference && reference.TryGetTarget(out HttpRequest request))
if (property is WeakReference<HttpRequest> reference && reference.TryGetTarget(out HttpRequest? request))
{
return request;
}
@ -49,7 +48,7 @@ namespace Microsoft.AspNetCore
/// </summary>
/// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictValidationEndpointType"/>.</returns>
public static OpenIddictValidationEndpointType GetOpenIddictValidationEndpointType([NotNull] this HttpContext context)
public static OpenIddictValidationEndpointType GetOpenIddictValidationEndpointType(this HttpContext context)
{
if (context == null)
{
@ -64,7 +63,7 @@ namespace Microsoft.AspNetCore
/// </summary>
/// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictRequest GetOpenIddictValidationRequest([NotNull] this HttpContext context)
public static OpenIddictRequest? GetOpenIddictValidationRequest(this HttpContext context)
{
if (context == null)
{
@ -79,7 +78,7 @@ namespace Microsoft.AspNetCore
/// </summary>
/// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictResponse"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictResponse GetOpenIddictValidationResponse([NotNull] this HttpContext context)
public static OpenIddictResponse? GetOpenIddictValidationResponse(this HttpContext context)
{
if (context == null)
{

5
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreOptions.cs

@ -14,9 +14,8 @@ namespace OpenIddict.Validation.AspNetCore
public class OpenIddictValidationAspNetCoreOptions : AuthenticationSchemeOptions
{
/// <summary>
/// Gets or sets the optional "realm" value returned to
/// the caller as part of the WWW-Authenticate header.
/// Gets or sets the optional "realm" value returned to the caller as part of the WWW-Authenticate header.
/// </summary>
public string Realm { get; set; }
public string? Realm { get; set; }
}
}

3
src/OpenIddict.Validation.DataProtection/IOpenIddictValidationDataProtectionFormatter.cs

@ -6,12 +6,11 @@
using System.IO;
using System.Security.Claims;
using JetBrains.Annotations;
namespace OpenIddict.Validation.DataProtection
{
public interface IOpenIddictValidationDataProtectionFormatter
{
ClaimsPrincipal ReadToken([NotNull] BinaryReader reader);
ClaimsPrincipal? ReadToken(BinaryReader reader);
}
}

5
src/OpenIddict.Validation.DataProtection/OpenIddict.Validation.DataProtection.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
@ -14,12 +15,12 @@
</ItemGroup>
<ItemGroup
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.1')) ">
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.0')) ">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup
Condition=" '$(TargetFrameworkIdentifier)' != '.NETCoreApp' Or $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.1')) ">
Condition=" '$(TargetFrameworkIdentifier)' != '.NETCoreApp' Or $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0')) ">
<PackageReference Include="Microsoft.AspNetCore.DataProtection" />
</ItemGroup>

13
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionBuilder.cs

@ -6,7 +6,6 @@
using System;
using System.ComponentModel;
using JetBrains.Annotations;
using Microsoft.AspNetCore.DataProtection;
using OpenIddict.Validation.DataProtection;
@ -22,7 +21,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictValidationDataProtectionBuilder"/>.
/// </summary>
/// <param name="services">The services collection.</param>
public OpenIddictValidationDataProtectionBuilder([NotNull] IServiceCollection services)
public OpenIddictValidationDataProtectionBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary>
@ -37,7 +36,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationDataProtectionBuilder"/>.</returns>
public OpenIddictValidationDataProtectionBuilder Configure([NotNull] Action<OpenIddictValidationDataProtectionOptions> configuration)
public OpenIddictValidationDataProtectionBuilder Configure(Action<OpenIddictValidationDataProtectionOptions> configuration)
{
if (configuration == null)
{
@ -55,7 +54,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="provider">The data protection provider used to create token protectors.</param>
/// <returns>The <see cref="OpenIddictValidationDataProtectionBuilder"/>.</returns>
public OpenIddictValidationDataProtectionBuilder UseDataProtectionProvider([NotNull] IDataProtectionProvider provider)
public OpenIddictValidationDataProtectionBuilder UseDataProtectionProvider(IDataProtectionProvider provider)
{
if (provider == null)
{
@ -70,7 +69,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="formatter">The formatter used to read tokens.</param>
/// <returns>The <see cref="OpenIddictValidationDataProtectionBuilder"/>.</returns>
public OpenIddictValidationDataProtectionBuilder UseFormatter([NotNull] IOpenIddictValidationDataProtectionFormatter formatter)
public OpenIddictValidationDataProtectionBuilder UseFormatter(IOpenIddictValidationDataProtectionFormatter formatter)
{
if (formatter == null)
{
@ -86,7 +85,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj);
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
@ -100,6 +99,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string? ToString() => base.ToString();
}
}

7
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionConfiguration.cs

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Options;
@ -23,10 +22,10 @@ namespace OpenIddict.Validation.DataProtection
/// Creates a new instance of the <see cref="OpenIddictValidationDataProtectionConfiguration"/> class.
/// </summary>
/// <param name="dataProtectionProvider">The ASP.NET Core Data Protection provider.</param>
public OpenIddictValidationDataProtectionConfiguration([NotNull] IDataProtectionProvider dataProtectionProvider)
public OpenIddictValidationDataProtectionConfiguration(IDataProtectionProvider dataProtectionProvider)
=> _dataProtectionProvider = dataProtectionProvider;
public void Configure([NotNull] OpenIddictValidationOptions options)
public void Configure(OpenIddictValidationOptions options)
{
if (options == null)
{
@ -43,7 +42,7 @@ namespace OpenIddict.Validation.DataProtection
/// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictValidationDataProtectionOptions options)
public void PostConfigure(string name, OpenIddictValidationDataProtectionOptions options)
{
if (options == null)
{

6
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionExtensions.cs

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using OpenIddict.Validation;
@ -26,7 +25,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationDataProtectionBuilder UseDataProtection([NotNull] this OpenIddictValidationBuilder builder)
public static OpenIddictValidationDataProtectionBuilder UseDataProtection(this OpenIddictValidationBuilder builder)
{
if (builder == null)
{
@ -57,8 +56,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationBuilder UseDataProtection(
[NotNull] this OpenIddictValidationBuilder builder,
[NotNull] Action<OpenIddictValidationDataProtectionBuilder> configuration)
this OpenIddictValidationBuilder builder, Action<OpenIddictValidationDataProtectionBuilder> configuration)
{
if (builder == null)
{

7
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs

@ -10,7 +10,6 @@ using System.Collections.Immutable;
using System.IO;
using System.Security.Claims;
using System.Text.Json;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
using Properties = OpenIddict.Validation.DataProtection.OpenIddictValidationDataProtectionConstants.Properties;
@ -19,7 +18,7 @@ namespace OpenIddict.Validation.DataProtection
{
public class OpenIddictValidationDataProtectionFormatter : IOpenIddictValidationDataProtectionFormatter
{
public ClaimsPrincipal ReadToken([NotNull] BinaryReader reader)
public ClaimsPrincipal? ReadToken(BinaryReader reader)
{
if (reader == null)
{
@ -58,7 +57,7 @@ namespace OpenIddict.Validation.DataProtection
.SetClaim(Claims.Private.TokenId, GetProperty(properties, Properties.InternalTokenId))
.SetClaim(Claims.Private.UserCodeLifetime, GetProperty(properties, Properties.UserCodeLifetime));
static (ClaimsPrincipal principal, IReadOnlyDictionary<string, string> properties) Read(BinaryReader reader)
static (ClaimsPrincipal? principal, IReadOnlyDictionary<string, string> properties) Read(BinaryReader reader)
{
// Read the version of the format used to serialize the ticket.
var version = reader.ReadInt32();
@ -175,7 +174,7 @@ namespace OpenIddict.Validation.DataProtection
return value;
}
static string GetProperty(IReadOnlyDictionary<string, string> properties, string name)
static string? GetProperty(IReadOnlyDictionary<string, string> properties, string name)
=> properties.TryGetValue(name, out var value) ? value : null;
static ImmutableArray<string> GetArrayProperty(IReadOnlyDictionary<string, string> properties, string name)

13
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionHandlers.cs

@ -9,7 +9,6 @@ using System.Collections.Immutable;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -41,7 +40,7 @@ namespace OpenIddict.Validation.DataProtection
{
private readonly IOptionsMonitor<OpenIddictValidationDataProtectionOptions> _options;
public ValidateDataProtectionToken([NotNull] IOptionsMonitor<OpenIddictValidationDataProtectionOptions> options)
public ValidateDataProtectionToken(IOptionsMonitor<OpenIddictValidationDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -54,14 +53,8 @@ namespace OpenIddict.Validation.DataProtection
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{

2
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionOptions.cs

@ -20,7 +20,7 @@ namespace OpenIddict.Validation.DataProtection
/// When this property is set to <c>null</c>, the data protection provider
/// is directly retrieved from the dependency injection container.
/// </summary>
public IDataProtectionProvider DataProtectionProvider { get; set; }
public IDataProtectionProvider DataProtectionProvider { get; set; } = default!;
/// <summary>
/// Gets or sets the formatter used to read Data Protection tokens.

1
src/OpenIddict.Validation.Owin/OpenIddict.Validation.Owin.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>

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

@ -6,7 +6,6 @@
using System;
using System.ComponentModel;
using JetBrains.Annotations;
using Microsoft.Owin.Security;
using OpenIddict.Validation.Owin;
using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -23,7 +22,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictValidationOwinBuilder"/>.
/// </summary>
/// <param name="services">The services collection.</param>
public OpenIddictValidationOwinBuilder([NotNull] IServiceCollection services)
public OpenIddictValidationOwinBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary>
@ -38,7 +37,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationOwinBuilder"/>.</returns>
public OpenIddictValidationOwinBuilder Configure([NotNull] Action<OpenIddictValidationOwinOptions> configuration)
public OpenIddictValidationOwinBuilder Configure(Action<OpenIddictValidationOwinOptions> configuration)
{
if (configuration == null)
{
@ -70,7 +69,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="realm">The issuer address.</param>
/// <returns>The <see cref="OpenIddictValidationOwinBuilder"/>.</returns>
public OpenIddictValidationOwinBuilder SetRealm([NotNull] string realm)
public OpenIddictValidationOwinBuilder SetRealm(string realm)
{
if (string.IsNullOrEmpty(realm))
{
@ -86,7 +85,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj);
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
@ -100,6 +99,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string? ToString() => base.ToString();
}
}

3
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinConfiguration.cs

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
namespace OpenIddict.Validation.Owin
@ -15,7 +14,7 @@ namespace OpenIddict.Validation.Owin
/// </summary>
public class OpenIddictValidationOwinConfiguration : IConfigureOptions<OpenIddictValidationOptions>
{
public void Configure([NotNull] OpenIddictValidationOptions options)
public void Configure(OpenIddictValidationOptions options)
{
if (options == null)
{

6
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinExtensions.cs

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using OpenIddict.Validation;
@ -27,7 +26,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationOwinBuilder"/>.</returns>
public static OpenIddictValidationOwinBuilder UseOwin([NotNull] this OpenIddictValidationBuilder builder)
public static OpenIddictValidationOwinBuilder UseOwin(this OpenIddictValidationBuilder builder)
{
if (builder == null)
{
@ -64,8 +63,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationBuilder UseOwin(
[NotNull] this OpenIddictValidationBuilder builder,
[NotNull] Action<OpenIddictValidationOwinBuilder> configuration)
this OpenIddictValidationBuilder builder, Action<OpenIddictValidationOwinBuilder> configuration)
{
if (builder == null)
{

34
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs

@ -6,9 +6,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Claims;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
@ -33,13 +33,14 @@ namespace OpenIddict.Validation.Owin
/// <param name="dispatcher">The OpenIddict validation provider used by this instance.</param>
/// <param name="factory">The OpenIddict validation factory used by this instance.</param>
public OpenIddictValidationOwinHandler(
[NotNull] IOpenIddictValidationDispatcher dispatcher,
[NotNull] IOpenIddictValidationFactory factory)
IOpenIddictValidationDispatcher dispatcher,
IOpenIddictValidationFactory factory)
{
_dispatcher = dispatcher;
_factory = factory;
}
/// <inheritdoc/>
protected override async Task InitializeCoreAsync()
{
// Note: the transaction may be already attached when replaying an OWIN request
@ -49,7 +50,7 @@ namespace OpenIddict.Validation.Owin
{
// Create a new transaction and attach the OWIN request to make it available to the OWIN handlers.
transaction = await _factory.CreateTransactionAsync();
transaction.Properties[typeof(IOwinRequest).FullName] = new WeakReference<IOwinRequest>(Request);
transaction.Properties[typeof(IOwinRequest).FullName!] = new WeakReference<IOwinRequest>(Request);
// Attach the OpenIddict validation transaction to the OWIN shared dictionary
// so that it can retrieved while performing sign-in/sign-out operations.
@ -60,9 +61,10 @@ namespace OpenIddict.Validation.Owin
await _dispatcher.DispatchAsync(context);
// Store the context in the transaction so that it can be retrieved from InvokeAsync().
transaction.SetProperty(typeof(ProcessRequestContext).FullName, context);
transaction.SetProperty(typeof(ProcessRequestContext).FullName!, context);
}
/// <inheritdoc/>
public override async Task<bool> InvokeAsync()
{
// Note: due to internal differences between ASP.NET Core and Katana, the request MUST start being processed
@ -72,7 +74,7 @@ namespace OpenIddict.Validation.Owin
var transaction = Context.Get<OpenIddictValidationTransaction>(typeof(OpenIddictValidationTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1165));
var context = transaction.GetProperty<ProcessRequestContext>(typeof(ProcessRequestContext).FullName) ??
var context = transaction.GetProperty<ProcessRequestContext>(typeof(ProcessRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1165));
if (context.IsRequestHandled)
@ -115,7 +117,8 @@ namespace OpenIddict.Validation.Owin
return false;
}
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
/// <inheritdoc/>
protected override async Task<AuthenticationTicket?> AuthenticateCoreAsync()
{
var transaction = Context.Get<OpenIddictValidationTransaction>(typeof(OpenIddictValidationTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1165));
@ -123,7 +126,7 @@ namespace OpenIddict.Validation.Owin
// Note: in many cases, the authentication token was already validated by the time this action is called
// (generally later in the pipeline, when using the pass-through mode). To avoid having to re-validate it,
// the authentication context is resolved from the transaction. If it's not available, a new one is created.
var context = transaction.GetProperty<ProcessAuthenticationContext>(typeof(ProcessAuthenticationContext).FullName);
var context = transaction.GetProperty<ProcessAuthenticationContext>(typeof(ProcessAuthenticationContext).FullName!);
if (context == null)
{
context = new ProcessAuthenticationContext(transaction);
@ -131,7 +134,7 @@ namespace OpenIddict.Validation.Owin
// Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the authentication result without triggering a new authentication flow.
transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName, context);
transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName!, context);
}
if (context.IsRequestHandled || context.IsRequestSkipped)
@ -149,7 +152,7 @@ namespace OpenIddict.Validation.Owin
return null;
}
var properties = new AuthenticationProperties(new Dictionary<string, string>
var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[OpenIddictValidationOwinConstants.Properties.Error] = context.Error,
[OpenIddictValidationOwinConstants.Properties.ErrorDescription] = context.ErrorDescription,
@ -161,17 +164,22 @@ namespace OpenIddict.Validation.Owin
else
{
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
Debug.Assert(!string.IsNullOrEmpty(context.Principal.GetTokenType()), SR.GetResourceString(SR.ID5009));
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID5010));
// Store the token to allow any OWIN/Katana component (e.g a controller)
// to retrieve it (e.g to make an API request to another application).
var properties = new AuthenticationProperties(new Dictionary<string, string>
var properties = new AuthenticationProperties(new Dictionary<string, string?>
{
[context.TokenType] = context.Token
[context.Principal.GetTokenType()!] = context.Token
});
return new AuthenticationTicket((ClaimsIdentity) context.Principal.Identity, properties);
}
}
/// <inheritdoc/>
protected override async Task TeardownCoreAsync()
{
// Note: OWIN authentication handlers cannot reliabily write to the response stream
@ -195,7 +203,7 @@ namespace OpenIddict.Validation.Owin
var transaction = Context.Get<OpenIddictValidationTransaction>(typeof(OpenIddictValidationTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1165));
transaction.Properties[typeof(AuthenticationProperties).FullName] = challenge.Properties ?? new AuthenticationProperties();
transaction.Properties[typeof(AuthenticationProperties).FullName!] = challenge.Properties ?? new AuthenticationProperties();
var context = new ProcessChallengeContext(transaction)
{

3
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlerFilters.cs

@ -6,7 +6,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Owin;
using static OpenIddict.Validation.OpenIddictValidationEvents;
@ -22,7 +21,7 @@ namespace OpenIddict.Validation.Owin
/// </summary>
public class RequireOwinRequest : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{

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

@ -8,12 +8,12 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Owin.Security;
@ -79,14 +79,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -117,7 +111,7 @@ namespace OpenIddict.Validation.Owin
return default;
}
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer) ||
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) ||
!issuer.IsWellFormedOriginalString())
{
context.Reject(
@ -150,14 +144,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -210,14 +198,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -275,14 +257,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -335,21 +311,15 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessChallengeContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName);
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties != null)
{
context.Response.Error = GetProperty(properties, Properties.Error);
@ -360,8 +330,8 @@ namespace OpenIddict.Validation.Owin
return default;
static string GetProperty(AuthenticationProperties properties, string name)
=> properties.Dictionary.TryGetValue(name, out string value) ? value : null;
static string? GetProperty(AuthenticationProperties properties, string name)
=> properties.Dictionary.TryGetValue(name, out string? value) ? value : null;
}
}
@ -382,20 +352,16 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -404,7 +370,7 @@ namespace OpenIddict.Validation.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
}
response.StatusCode = context.Response.Error switch
response.StatusCode = context.Transaction.Response.Error switch
{
null => 200,
@ -438,14 +404,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -477,7 +437,7 @@ namespace OpenIddict.Validation.Owin
{
private readonly IOptionsMonitor<OpenIddictValidationOwinOptions> _options;
public AttachWwwAuthenticateHeader([NotNull] IOptionsMonitor<OpenIddictValidationOwinOptions> options)
public AttachWwwAuthenticateHeader(IOptionsMonitor<OpenIddictValidationOwinOptions> options)
=> _options = options;
/// <summary>
@ -491,20 +451,16 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -513,12 +469,12 @@ namespace OpenIddict.Validation.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
}
if (string.IsNullOrEmpty(context.Response.Error))
if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{
return default;
}
var scheme = context.Response.Error switch
var scheme = context.Transaction.Response.Error switch
{
Errors.InvalidToken => Schemes.Bearer,
Errors.MissingToken => Schemes.Bearer,
@ -541,11 +497,11 @@ namespace OpenIddict.Validation.Owin
parameters[Parameters.Realm] = _options.CurrentValue.Realm;
}
foreach (var parameter in context.Response.GetParameters())
foreach (var parameter in context.Transaction.Response.GetParameters())
{
// Note: the error details are only included if the error was not caused by a missing token, as recommended
// by the OAuth 2.0 bearer specification: https://tools.ietf.org/html/rfc6750#section-3.1.
if (string.Equals(context.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
if (string.Equals(context.Transaction.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
(string.Equals(parameter.Key, Parameters.Error, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal)))
@ -554,7 +510,7 @@ namespace OpenIddict.Validation.Owin
}
// Ignore values that can't be represented as unique strings.
var value = (string) parameter.Value;
var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value))
{
continue;
@ -605,14 +561,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -633,7 +583,7 @@ namespace OpenIddict.Validation.Owin
return default;
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Transaction.Response);
context.HandleRequest();
return default;
@ -657,14 +607,8 @@ namespace OpenIddict.Validation.Owin
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -679,10 +623,10 @@ namespace OpenIddict.Validation.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Response, new JsonSerializerOptions
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false

15
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHelpers.cs

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using Microsoft.Owin;
using OpenIddict.Abstractions;
using OpenIddict.Validation;
@ -26,7 +25,7 @@ namespace Owin
/// </summary>
/// <param name="app">The application builder used to register middleware instances.</param>
/// <returns>The <see cref="IAppBuilder"/>.</returns>
public static IAppBuilder UseOpenIddictValidation([NotNull] this IAppBuilder app)
public static IAppBuilder UseOpenIddictValidation(this IAppBuilder app)
{
if (app == null)
{
@ -41,19 +40,19 @@ namespace Owin
/// </summary>
/// <param name="transaction">The transaction instance.</param>
/// <returns>The <see cref="IOwinRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static IOwinRequest GetOwinRequest([NotNull] this OpenIddictValidationTransaction transaction)
public static IOwinRequest? GetOwinRequest(this OpenIddictValidationTransaction transaction)
{
if (transaction == null)
{
throw new ArgumentNullException(nameof(transaction));
}
if (!transaction.Properties.TryGetValue(typeof(IOwinRequest).FullName, out object property))
if (!transaction.Properties.TryGetValue(typeof(IOwinRequest).FullName!, out object? property))
{
return null;
}
if (property is WeakReference<IOwinRequest> reference && reference.TryGetTarget(out IOwinRequest request))
if (property is WeakReference<IOwinRequest> reference && reference.TryGetTarget(out IOwinRequest? request))
{
return request;
}
@ -66,7 +65,7 @@ namespace Owin
/// </summary>
/// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictValidationEndpointType"/>.</returns>
public static OpenIddictValidationEndpointType GetOpenIddictValidationEndpointType([NotNull] this IOwinContext context)
public static OpenIddictValidationEndpointType GetOpenIddictValidationEndpointType(this IOwinContext context)
{
if (context == null)
{
@ -81,7 +80,7 @@ namespace Owin
/// </summary>
/// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictRequest GetOpenIddictValidationRequest([NotNull] this IOwinContext context)
public static OpenIddictRequest? GetOpenIddictValidationRequest(this IOwinContext context)
{
if (context == null)
{
@ -96,7 +95,7 @@ namespace Owin
/// </summary>
/// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictResponse"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictResponse GetOpenIddictValidationResponse([NotNull] this IOwinContext context)
public static OpenIddictResponse? GetOpenIddictValidationResponse(this IOwinContext context)
{
if (context == null)
{

9
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinMiddleware.cs

@ -4,7 +4,6 @@
* the license and the contributors participating to this project.
*/
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
using Microsoft.Owin;
using Microsoft.Owin.Security.Infrastructure;
@ -30,10 +29,10 @@ namespace OpenIddict.Validation.Owin
/// <param name="dispatcher">The OpenIddict validation dispatcher.</param>
/// <param name="factory">The OpenIddict validation factory.</param>
public OpenIddictValidationOwinMiddleware(
[CanBeNull] OwinMiddleware next,
[NotNull] IOptionsMonitor<OpenIddictValidationOwinOptions> options,
[NotNull] IOpenIddictValidationDispatcher dispatcher,
[NotNull] IOpenIddictValidationFactory factory)
OwinMiddleware? next,
IOptionsMonitor<OpenIddictValidationOwinOptions> options,
IOpenIddictValidationDispatcher dispatcher,
IOpenIddictValidationFactory factory)
: base(next, options.CurrentValue)
{
_dispatcher = dispatcher;

5
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinMiddlewareFactory.cs

@ -6,7 +6,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Owin;
@ -24,7 +23,7 @@ namespace OpenIddict.Validation.Owin
/// Creates a new instance of the <see cref="OpenIddictValidationOwinMiddlewareFactory"/> class.
/// </summary>
/// <param name="next">The next middleware in the pipeline, if applicable.</param>
public OpenIddictValidationOwinMiddlewareFactory([CanBeNull] OwinMiddleware next)
public OpenIddictValidationOwinMiddlewareFactory(OwinMiddleware? next)
: base(next)
{
}
@ -38,7 +37,7 @@ namespace OpenIddict.Validation.Owin
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override Task Invoke([NotNull] IOwinContext context)
public override Task Invoke(IOwinContext context)
{
if (context == null)
{

5
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinOptions.cs

@ -21,9 +21,8 @@ namespace OpenIddict.Validation.Owin
=> AuthenticationMode = AuthenticationMode.Passive;
/// <summary>
/// Gets or sets the optional "realm" value returned to
/// the caller as part of the WWW-Authenticate header.
/// Gets or sets the optional "realm" value returned to the caller as part of the WWW-Authenticate header.
/// </summary>
public string Realm { get; set; }
public string? Realm { get; set; }
}
}

1
src/OpenIddict.Validation.ServerIntegration/OpenIddict.Validation.ServerIntegration.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>

9
src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationBuilder.cs

@ -6,7 +6,6 @@
using System;
using System.ComponentModel;
using JetBrains.Annotations;
using OpenIddict.Validation.ServerIntegration;
namespace Microsoft.Extensions.DependencyInjection
@ -20,7 +19,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictValidationBuilder"/>.
/// </summary>
/// <param name="services">The services collection.</param>
public OpenIddictValidationServerIntegrationBuilder([NotNull] IServiceCollection services)
public OpenIddictValidationServerIntegrationBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary>
@ -35,7 +34,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationServerIntegrationBuilder"/>.</returns>
public OpenIddictValidationServerIntegrationBuilder Configure([NotNull] Action<OpenIddictValidationServerIntegrationOptions> configuration)
public OpenIddictValidationServerIntegrationBuilder Configure(Action<OpenIddictValidationServerIntegrationOptions> configuration)
{
if (configuration == null)
{
@ -53,7 +52,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj);
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
@ -67,6 +66,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string? ToString() => base.ToString();
}
}

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

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using OpenIddict.Server;
@ -25,7 +24,7 @@ namespace OpenIddict.Validation.ServerIntegration
/// Creates a new instance of the <see cref="OpenIddictValidationServerIntegrationConfiguration"/> class.
/// </summary>
/// <param name="options">The OpenIddict server options.</param>
public OpenIddictValidationServerIntegrationConfiguration([NotNull] IOptionsMonitor<OpenIddictServerOptions> options)
public OpenIddictValidationServerIntegrationConfiguration(IOptionsMonitor<OpenIddictServerOptions> options)
=> _options = options;
/// <summary>
@ -33,7 +32,7 @@ namespace OpenIddict.Validation.ServerIntegration
/// and ensures that the configuration is in a consistent and valid state.
/// </summary>
/// <param name="options">The options instance to initialize.</param>
public void Configure([NotNull] OpenIddictValidationOptions options)
public void Configure(OpenIddictValidationOptions options)
{
if (options == null)
{
@ -66,7 +65,7 @@ namespace OpenIddict.Validation.ServerIntegration
/// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictValidationOptions options)
public void PostConfigure(string name, OpenIddictValidationOptions options)
{
if (options == null)
{

6
src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationExtensions.cs

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using OpenIddict.Validation;
@ -25,7 +24,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationServerIntegrationBuilder UseLocalServer([NotNull] this OpenIddictValidationBuilder builder)
public static OpenIddictValidationServerIntegrationBuilder UseLocalServer(this OpenIddictValidationBuilder builder)
{
if (builder == null)
{
@ -51,8 +50,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
public static OpenIddictValidationBuilder UseLocalServer(
[NotNull] this OpenIddictValidationBuilder builder,
[NotNull] Action<OpenIddictValidationServerIntegrationBuilder> configuration)
this OpenIddictValidationBuilder builder, Action<OpenIddictValidationServerIntegrationBuilder> configuration)
{
if (builder == null)
{

1
src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>

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

@ -7,7 +7,6 @@
using System;
using System.ComponentModel;
using System.Net.Http;
using JetBrains.Annotations;
using OpenIddict.Validation.SystemNetHttp;
using Polly;
@ -22,7 +21,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictValidationBuilder"/>.
/// </summary>
/// <param name="services">The services collection.</param>
public OpenIddictValidationSystemNetHttpBuilder([NotNull] IServiceCollection services)
public OpenIddictValidationSystemNetHttpBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary>
@ -37,7 +36,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationSystemNetHttpBuilder"/>.</returns>
public OpenIddictValidationSystemNetHttpBuilder Configure([NotNull] Action<OpenIddictValidationSystemNetHttpOptions> configuration)
public OpenIddictValidationSystemNetHttpBuilder Configure(Action<OpenIddictValidationSystemNetHttpOptions> configuration)
{
if (configuration == null)
{
@ -54,7 +53,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="policy">The HTTP Polly error policy.</param>
/// <returns>The <see cref="OpenIddictValidationSystemNetHttpBuilder"/>.</returns>
public OpenIddictValidationSystemNetHttpBuilder SetHttpErrorPolicy([CanBeNull] IAsyncPolicy<HttpResponseMessage> policy)
public OpenIddictValidationSystemNetHttpBuilder SetHttpErrorPolicy(IAsyncPolicy<HttpResponseMessage> policy)
=> Configure(options => options.HttpErrorPolicy = policy);
/// <summary>
@ -63,7 +62,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj);
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
@ -77,6 +76,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string? ToString() => base.ToString();
}
}

13
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpConfiguration.cs

@ -7,7 +7,6 @@
using System;
using System.Diagnostics;
using System.Net.Http.Headers;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Options;
@ -23,11 +22,11 @@ namespace OpenIddict.Validation.SystemNetHttp
#if !SUPPORTS_SERVICE_PROVIDER_IN_HTTP_MESSAGE_HANDLER_BUILDER
private readonly IServiceProvider _provider;
public OpenIddictValidationSystemNetHttpConfiguration([NotNull] IServiceProvider provider)
public OpenIddictValidationSystemNetHttpConfiguration(IServiceProvider provider)
=> _provider = provider;
#endif
public void Configure([NotNull] OpenIddictValidationOptions options)
public void Configure(OpenIddictValidationOptions options)
{
if (options == null)
{
@ -38,10 +37,10 @@ namespace OpenIddict.Validation.SystemNetHttp
options.Handlers.AddRange(OpenIddictValidationSystemNetHttpHandlers.DefaultHandlers);
}
public void Configure([NotNull] HttpClientFactoryOptions options)
public void Configure(HttpClientFactoryOptions options)
=> Debug.Fail("This infrastructure method shouldn't be called.");
public void Configure([CanBeNull] string name, [NotNull] HttpClientFactoryOptions options)
public void Configure(string name, HttpClientFactoryOptions options)
{
if (options == null)
{
@ -58,8 +57,8 @@ namespace OpenIddict.Validation.SystemNetHttp
options.HttpClientActions.Add(client =>
{
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(
productName: assembly.Name,
productVersion: assembly.Version.ToString()));
productName: assembly.Name!,
productVersion: assembly.Version!.ToString()));
});
options.HttpMessageHandlerBuilderActions.Add(builder =>

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

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Options;
@ -28,7 +27,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationSystemNetHttpBuilder UseSystemNetHttp([NotNull] this OpenIddictValidationBuilder builder)
public static OpenIddictValidationSystemNetHttpBuilder UseSystemNetHttp(this OpenIddictValidationBuilder builder)
{
if (builder == null)
{
@ -62,8 +61,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
public static OpenIddictValidationBuilder UseSystemNetHttp(
[NotNull] this OpenIddictValidationBuilder builder,
[NotNull] Action<OpenIddictValidationSystemNetHttpBuilder> configuration)
this OpenIddictValidationBuilder builder, Action<OpenIddictValidationSystemNetHttpBuilder> configuration)
{
if (builder == null)
{

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

@ -7,7 +7,6 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Validation.OpenIddictValidationEvents;
namespace OpenIddict.Validation.SystemNetHttp
@ -20,7 +19,7 @@ namespace OpenIddict.Validation.SystemNetHttp
/// </summary>
public class RequireHttpMetadataAddress : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{

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

@ -6,11 +6,11 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Abstractions.OpenIddictConstants;
using static OpenIddict.Validation.OpenIddictValidationEvents;
using static OpenIddict.Validation.SystemNetHttp.OpenIddictValidationSystemNetHttpHandlerFilters;
@ -52,13 +52,16 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] PrepareIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(PrepareIntrospectionRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context.Transaction.GetHttpRequestMessage();
@ -97,7 +100,7 @@ namespace OpenIddict.Validation.SystemNetHttp
context.Request.ClientId = context.Request.ClientSecret = null;
}
static string EscapeDataString(string value)
static string? EscapeDataString(string? value)
{
if (string.IsNullOrEmpty(value))
{

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

@ -8,12 +8,12 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
using static OpenIddict.Validation.OpenIddictValidationEvents;
using static OpenIddict.Validation.SystemNetHttp.OpenIddictValidationSystemNetHttpHandlerFilters;
@ -45,7 +45,8 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -57,7 +58,7 @@ namespace OpenIddict.Validation.SystemNetHttp
request.Headers.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
// Store the HttpRequestMessage in the transaction properties.
context.Transaction.Properties[typeof(HttpRequestMessage).FullName] = request;
context.Transaction.Properties[typeof(HttpRequestMessage).FullName!] = request;
return default;
}
@ -79,7 +80,8 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -91,7 +93,7 @@ namespace OpenIddict.Validation.SystemNetHttp
request.Headers.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
// Store the HttpRequestMessage in the transaction properties.
context.Transaction.Properties[typeof(HttpRequestMessage).FullName] = request;
context.Transaction.Properties[typeof(HttpRequestMessage).FullName!] = request;
return default;
}
@ -113,13 +115,16 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context.Transaction.GetHttpRequestMessage();
@ -132,8 +137,8 @@ namespace OpenIddict.Validation.SystemNetHttp
// query strings from existing key/value pairs. To work around this limitation,
// a FormUrlEncodedContent is instantiated and used to manually create the URL.
using var content = new FormUrlEncodedContent(
from parameter in context.Request.GetParameters()
let values = (string[]) parameter.Value
from parameter in context.Transaction.Request.GetParameters()
let values = (string[]?) parameter.Value
where values != null
from value in values
select new KeyValuePair<string, string>(parameter.Key, value));
@ -163,13 +168,16 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to System.Net.Http requests. If the HTTP request cannot be resolved,
// this may indicate that the request was incorrectly processed by another client stack.
var request = context.Transaction.GetHttpRequestMessage();
@ -179,8 +187,8 @@ namespace OpenIddict.Validation.SystemNetHttp
}
request.Content = new FormUrlEncodedContent(
from parameter in context.Request.GetParameters()
let values = (string[]) parameter.Value
from parameter in context.Transaction.Request.GetParameters()
let values = (string[]?) parameter.Value
where values != null
from value in values
select new KeyValuePair<string, string>(parameter.Key, value));
@ -196,7 +204,7 @@ namespace OpenIddict.Validation.SystemNetHttp
{
private readonly IHttpClientFactory _factory;
public SendHttpRequest([NotNull] IHttpClientFactory factory)
public SendHttpRequest(IHttpClientFactory factory)
=> _factory = factory;
/// <summary>
@ -210,7 +218,8 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -239,7 +248,7 @@ namespace OpenIddict.Validation.SystemNetHttp
}
// Store the HttpResponseMessage in the transaction properties.
context.Transaction.Properties[typeof(HttpResponseMessage).FullName] = response;
context.Transaction.Properties[typeof(HttpResponseMessage).FullName!] = response;
}
}
@ -259,7 +268,8 @@ namespace OpenIddict.Validation.SystemNetHttp
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -279,7 +289,7 @@ namespace OpenIddict.Validation.SystemNetHttp
// Note: ReadFromJsonAsync() automatically validates the content type and the content encoding
// and transcode the response stream if a non-UTF-8 response is returned by the remote server.
context.Response = await response.Content.ReadFromJsonAsync<OpenIddictResponse>();
context.Transaction.Response = await response.Content.ReadFromJsonAsync<OpenIddictResponse>();
}
}
}

9
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHelpers.cs

@ -4,7 +4,6 @@
* the license and the contributors participating to this project.
*/
using JetBrains.Annotations;
using OpenIddict.Validation;
namespace System.Net.Http
@ -19,15 +18,15 @@ namespace System.Net.Http
/// </summary>
/// <param name="transaction">The transaction instance.</param>
/// <returns>The <see cref="HttpRequestMessage"/> instance or <c>null</c> if it couldn't be found.</returns>
public static HttpRequestMessage GetHttpRequestMessage([NotNull] this OpenIddictValidationTransaction transaction)
=> transaction.GetProperty<HttpRequestMessage>(typeof(HttpRequestMessage).FullName);
public static HttpRequestMessage? GetHttpRequestMessage(this OpenIddictValidationTransaction transaction)
=> transaction.GetProperty<HttpRequestMessage>(typeof(HttpRequestMessage).FullName!);
/// <summary>
/// Gets the <see cref="HttpResponseMessage"/> associated with the current context.
/// </summary>
/// <param name="transaction">The transaction instance.</param>
/// <returns>The <see cref="HttpResponseMessage"/> instance or <c>null</c> if it couldn't be found.</returns>
public static HttpResponseMessage GetHttpResponseMessage([NotNull] this OpenIddictValidationTransaction transaction)
=> transaction.GetProperty<HttpResponseMessage>(typeof(HttpResponseMessage).FullName);
public static HttpResponseMessage? GetHttpResponseMessage(this OpenIddictValidationTransaction transaction)
=> transaction.GetProperty<HttpResponseMessage>(typeof(HttpResponseMessage).FullName!);
}
}

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

@ -20,7 +20,7 @@ namespace OpenIddict.Validation.SystemNetHttp
/// <summary>
/// Gets or sets the HTTP Polly error policy used by the internal OpenIddict HTTP clients.
/// </summary>
public IAsyncPolicy<HttpResponseMessage> HttpErrorPolicy { get; set; }
public IAsyncPolicy<HttpResponseMessage>? HttpErrorPolicy { get; set; }
= HttpPolicyExtensions.HandleTransientHttpError()
.OrResult(response => response.StatusCode == HttpStatusCode.NotFound)
.WaitAndRetryAsync(4, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

3
src/OpenIddict.Validation/IOpenIddictValidationDispatcher.cs

@ -5,13 +5,12 @@
*/
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Validation.OpenIddictValidationEvents;
namespace OpenIddict.Validation
{
public interface IOpenIddictValidationDispatcher
{
ValueTask DispatchAsync<TContext>([NotNull] TContext context) where TContext : BaseContext;
ValueTask DispatchAsync<TContext>(TContext context) where TContext : BaseContext;
}
}

3
src/OpenIddict.Validation/IOpenIddictValidationHandler.cs

@ -5,7 +5,6 @@
*/
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Validation.OpenIddictValidationEvents;
namespace OpenIddict.Validation
@ -23,6 +22,6 @@ namespace OpenIddict.Validation
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
ValueTask HandleAsync([NotNull] TContext context);
ValueTask HandleAsync(TContext context);
}
}

3
src/OpenIddict.Validation/IOpenIddictValidationHandlerFilter.cs

@ -5,13 +5,12 @@
*/
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Validation.OpenIddictValidationEvents;
namespace OpenIddict.Validation
{
public interface IOpenIddictValidationHandlerFilter<in TContext> where TContext : BaseContext
{
ValueTask<bool> IsActiveAsync([NotNull] TContext context);
ValueTask<bool> IsActiveAsync(TContext context);
}
}

1
src/OpenIddict.Validation/OpenIddict.Validation.csproj

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFrameworks>net461;net472;netcoreapp2.1;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>

49
src/OpenIddict.Validation/OpenIddictValidationBuilder.cs

@ -11,7 +11,6 @@ using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
@ -30,7 +29,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictValidationBuilder"/>.
/// </summary>
/// <param name="services">The services collection.</param>
public OpenIddictValidationBuilder([NotNull] IServiceCollection services)
public OpenIddictValidationBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary>
@ -47,7 +46,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictValidationBuilder AddEventHandler<TContext>(
[NotNull] Action<OpenIddictValidationHandlerDescriptor.Builder<TContext>> configuration)
Action<OpenIddictValidationHandlerDescriptor.Builder<TContext>> configuration)
where TContext : OpenIddictValidationEvents.BaseContext
{
if (configuration == null)
@ -70,7 +69,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="descriptor">The handler descriptor.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictValidationBuilder AddEventHandler([NotNull] OpenIddictValidationHandlerDescriptor descriptor)
public OpenIddictValidationBuilder AddEventHandler(OpenIddictValidationHandlerDescriptor descriptor)
{
if (descriptor == null)
{
@ -89,7 +88,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="descriptor">The descriptor corresponding to the handler to remove.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictValidationBuilder RemoveEventHandler([NotNull] OpenIddictValidationHandlerDescriptor descriptor)
public OpenIddictValidationBuilder RemoveEventHandler(OpenIddictValidationHandlerDescriptor descriptor)
{
if (descriptor == null)
{
@ -118,7 +117,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder Configure([NotNull] Action<OpenIddictValidationOptions> configuration)
public OpenIddictValidationBuilder Configure(Action<OpenIddictValidationOptions> configuration)
{
if (configuration == null)
{
@ -135,7 +134,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="credentials">The encrypting credentials.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCredentials([NotNull] EncryptingCredentials credentials)
public OpenIddictValidationBuilder AddEncryptionCredentials(EncryptingCredentials credentials)
{
if (credentials == null)
{
@ -150,7 +149,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="key">The security key.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionKey([NotNull] SecurityKey key)
public OpenIddictValidationBuilder AddEncryptionKey(SecurityKey key)
{
if (key == null)
{
@ -184,7 +183,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="certificate">The encryption certificate.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCertificate([NotNull] X509Certificate2 certificate)
public OpenIddictValidationBuilder AddEncryptionCertificate(X509Certificate2 certificate)
{
if (certificate == null)
{
@ -218,7 +217,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="password">The password used to open the certificate.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCertificate(
[NotNull] Assembly assembly, [NotNull] string resource, [NotNull] string password)
Assembly assembly, string resource, string password)
#if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS.
=> AddEncryptionCertificate(assembly, resource, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
@ -237,8 +236,8 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="flags">An enumeration of flags indicating how and where to store the private key of the certificate.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCertificate(
[NotNull] Assembly assembly, [NotNull] string resource,
[NotNull] string password, X509KeyStorageFlags flags)
Assembly assembly, string resource,
string password, X509KeyStorageFlags flags)
{
if (assembly == null)
{
@ -270,7 +269,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="stream">The stream containing the certificate.</param>
/// <param name="password">The password used to open the certificate.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCertificate([NotNull] Stream stream, [NotNull] string password)
public OpenIddictValidationBuilder AddEncryptionCertificate(Stream stream, string password)
#if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS.
=> AddEncryptionCertificate(stream, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
@ -293,7 +292,7 @@ namespace Microsoft.Extensions.DependencyInjection
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The X.509 certificate is attached to the server options.")]
public OpenIddictValidationBuilder AddEncryptionCertificate(
[NotNull] Stream stream, [NotNull] string password, X509KeyStorageFlags flags)
Stream stream, string password, X509KeyStorageFlags flags)
{
if (stream == null)
{
@ -316,7 +315,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X.509 store.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCertificate([NotNull] string thumbprint)
public OpenIddictValidationBuilder AddEncryptionCertificate(string thumbprint)
{
if (string.IsNullOrEmpty(thumbprint))
{
@ -350,7 +349,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="location">The location of the X.509 store.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddEncryptionCertificate(
[NotNull] string thumbprint, StoreName name, StoreLocation location)
string thumbprint, StoreName name, StoreLocation location)
{
if (string.IsNullOrEmpty(thumbprint))
{
@ -378,7 +377,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="audiences">The audiences valid for this resource server.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder AddAudiences([NotNull] params string[] audiences)
public OpenIddictValidationBuilder AddAudiences(params string[] audiences)
{
if (audiences == null)
{
@ -419,7 +418,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="configuration">The server configuration.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder SetConfiguration([NotNull] OpenIdConnectConfiguration configuration)
public OpenIddictValidationBuilder SetConfiguration(OpenIdConnectConfiguration configuration)
{
if (configuration == null)
{
@ -435,7 +434,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="identifier">The client identifier.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder SetClientId([NotNull] string identifier)
public OpenIddictValidationBuilder SetClientId(string identifier)
{
if (string.IsNullOrEmpty(identifier))
{
@ -451,7 +450,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="secret">The client secret.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder SetClientSecret([NotNull] string secret)
public OpenIddictValidationBuilder SetClientSecret(string secret)
{
if (string.IsNullOrEmpty(secret))
{
@ -467,7 +466,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="address">The issuer address.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder SetIssuer([NotNull] Uri address)
public OpenIddictValidationBuilder SetIssuer(Uri address)
{
if (address == null)
{
@ -483,14 +482,14 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <param name="address">The issuer address.</param>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public OpenIddictValidationBuilder SetIssuer([NotNull] string address)
public OpenIddictValidationBuilder SetIssuer(string address)
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException(SR.GetResourceString(SR.ID1125), nameof(address));
}
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID1126), nameof(address));
}
@ -511,7 +510,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param>
/// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj);
public override bool Equals(object? obj) => base.Equals(obj);
/// <summary>
/// Serves as the default hash function.
@ -525,6 +524,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary>
/// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();
public override string? ToString() => base.ToString();
}
}

72
src/OpenIddict.Validation/OpenIddictValidationConfiguration.cs

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
@ -23,7 +22,7 @@ namespace OpenIddict.Validation
{
private readonly OpenIddictValidationService _service;
public OpenIddictValidationConfiguration([NotNull] OpenIddictValidationService service)
public OpenIddictValidationConfiguration(OpenIddictValidationService service)
=> _service = service;
/// <summary>
@ -32,7 +31,7 @@ namespace OpenIddict.Validation
/// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictValidationOptions options)
public void PostConfigure(string name, OpenIddictValidationOptions options)
{
if (options == null)
{
@ -91,55 +90,52 @@ namespace OpenIddict.Validation
throw new InvalidOperationException(SR.GetResourceString(SR.ID1086));
}
if (options.Configuration == null && options.ConfigurationManager == null)
if (options.ConfigurationManager == null)
{
if (!options.Handlers.Any(descriptor => descriptor.ContextType == typeof(ApplyConfigurationRequestContext)) ||
!options.Handlers.Any(descriptor => descriptor.ContextType == typeof(ApplyCryptographyRequestContext)))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1134));
}
if (options.MetadataAddress == null)
if (options.Configuration != null)
{
options.MetadataAddress = new Uri(".well-known/openid-configuration", UriKind.Relative);
options.ConfigurationManager = new StaticConfigurationManager<OpenIdConnectConfiguration>(options.Configuration);
}
if (!options.MetadataAddress.IsAbsoluteUri)
else
{
if (options.Issuer == null || !options.Issuer.IsAbsoluteUri)
if (!options.Handlers.Any(descriptor => descriptor.ContextType == typeof(ApplyConfigurationRequestContext)) ||
!options.Handlers.Any(descriptor => descriptor.ContextType == typeof(ApplyCryptographyRequestContext)))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1135));
throw new InvalidOperationException(SR.GetResourceString(SR.ID1134));
}
if (!string.IsNullOrEmpty(options.Issuer.Fragment) || !string.IsNullOrEmpty(options.Issuer.Query))
if (options.MetadataAddress == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1136));
options.MetadataAddress = new Uri(".well-known/openid-configuration", UriKind.Relative);
}
if (!options.Issuer.OriginalString.EndsWith("/"))
if (!options.MetadataAddress.IsAbsoluteUri)
{
options.Issuer = new Uri(options.Issuer.OriginalString + "/", UriKind.Absolute);
if (options.Issuer == null || !options.Issuer.IsAbsoluteUri)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1135));
}
if (!string.IsNullOrEmpty(options.Issuer.Fragment) || !string.IsNullOrEmpty(options.Issuer.Query))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1136));
}
if (!options.Issuer.OriginalString.EndsWith("/"))
{
options.Issuer = new Uri(options.Issuer.OriginalString + "/", UriKind.Absolute);
}
if (options.MetadataAddress.OriginalString.StartsWith("/"))
{
options.MetadataAddress = new Uri(options.MetadataAddress.OriginalString.Substring(
1, options.MetadataAddress.OriginalString.Length - 1), UriKind.Relative);
}
options.MetadataAddress = new Uri(options.Issuer, options.MetadataAddress);
}
if (options.MetadataAddress.OriginalString.StartsWith("/"))
{
options.MetadataAddress = new Uri(options.MetadataAddress.OriginalString.Substring(
1, options.MetadataAddress.OriginalString.Length - 1), UriKind.Relative);
}
options.MetadataAddress = new Uri(options.Issuer, options.MetadataAddress);
}
}
if (options.ConfigurationManager == null)
{
if (options.Configuration != null)
{
options.ConfigurationManager = new StaticConfigurationManager<OpenIdConnectConfiguration>(options.Configuration);
}
else
{
options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
options.MetadataAddress.AbsoluteUri, new OpenIddictValidationRetriever(_service))
{

9
src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs

@ -7,7 +7,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using static OpenIddict.Validation.OpenIddictValidationEvents;
@ -25,16 +24,16 @@ namespace OpenIddict.Validation
/// Creates a new instance of the <see cref="OpenIddictValidationDispatcher"/> class.
/// </summary>
public OpenIddictValidationDispatcher(
[NotNull] ILogger<OpenIddictValidationDispatcher> logger,
[NotNull] IOptionsMonitor<OpenIddictValidationOptions> options,
[NotNull] IServiceProvider provider)
ILogger<OpenIddictValidationDispatcher> logger,
IOptionsMonitor<OpenIddictValidationOptions> options,
IServiceProvider provider)
{
_logger = logger;
_options = options;
_provider = provider;
}
public async ValueTask DispatchAsync<TContext>([NotNull] TContext context) where TContext : BaseContext
public async ValueTask DispatchAsync<TContext>(TContext context) where TContext : BaseContext
{
if (context == null)
{

126
src/OpenIddict.Validation/OpenIddictValidationEvents.Discovery.cs

@ -4,9 +4,9 @@
* the license and the contributors participating to this project.
*/
using JetBrains.Annotations;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions;
namespace OpenIddict.Validation
{
@ -21,10 +21,19 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="PrepareConfigurationRequestContext"/> class.
/// </summary>
public PrepareConfigurationRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public PrepareConfigurationRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -36,10 +45,19 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ApplyConfigurationRequestContext"/> class.
/// </summary>
public ApplyConfigurationRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public ApplyConfigurationRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -51,10 +69,28 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ExtractConfigurationResponseContext"/> class.
/// </summary>
public ExtractConfigurationResponseContext([NotNull] OpenIddictValidationTransaction transaction)
public ExtractConfigurationResponseContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictResponse? Response
{
get => Transaction.Response;
set => Transaction.Response = value;
}
}
/// <summary>
@ -65,11 +101,29 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="HandleConfigurationResponseContext"/> class.
/// </summary>
public HandleConfigurationResponseContext([NotNull] OpenIddictValidationTransaction transaction)
public HandleConfigurationResponseContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response!;
set => Transaction.Response = value;
}
/// <summary>
/// Gets the OpenID Connect configuration.
/// </summary>
@ -85,10 +139,19 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="PrepareCryptographyRequestContext"/> class.
/// </summary>
public PrepareCryptographyRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public PrepareCryptographyRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -100,10 +163,19 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ApplyCryptographyRequestContext"/> class.
/// </summary>
public ApplyCryptographyRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public ApplyCryptographyRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -115,10 +187,28 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ExtractCryptographyResponseContext"/> class.
/// </summary>
public ExtractCryptographyResponseContext([NotNull] OpenIddictValidationTransaction transaction)
public ExtractCryptographyResponseContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictResponse? Response
{
get => Transaction.Response;
set => Transaction.Response = value;
}
}
/// <summary>
@ -129,11 +219,29 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="HandleCryptographyResponseContext"/> class.
/// </summary>
public HandleCryptographyResponseContext([NotNull] OpenIddictValidationTransaction transaction)
public HandleCryptographyResponseContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response!;
set => Transaction.Response = value;
}
/// <summary>
/// Gets the security keys.
/// </summary>

74
src/OpenIddict.Validation/OpenIddictValidationEvents.Introspection.cs

@ -5,7 +5,7 @@
*/
using System.Security.Claims;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
namespace OpenIddict.Validation
{
@ -20,20 +20,29 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="PrepareIntrospectionRequestContext"/> class.
/// </summary>
public PrepareIntrospectionRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public PrepareIntrospectionRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the token sent to the introspection endpoint.
/// </summary>
public string Token { get; set; }
public string? Token { get; set; }
/// <summary>
/// Gets or sets the token type sent to the introspection endpoint.
/// </summary>
public string TokenType { get; set; }
public string? TokenType { get; set; }
}
/// <summary>
@ -45,10 +54,19 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ApplyIntrospectionRequestContext"/> class.
/// </summary>
public ApplyIntrospectionRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public ApplyIntrospectionRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -60,10 +78,28 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ExtractIntrospectionResponseContext"/> class.
/// </summary>
public ExtractIntrospectionResponseContext([NotNull] OpenIddictValidationTransaction transaction)
public ExtractIntrospectionResponseContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictResponse? Response
{
get => Transaction.Response;
set => Transaction.Response = value;
}
}
/// <summary>
@ -74,25 +110,43 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="HandleIntrospectionResponseContext"/> class.
/// </summary>
public HandleIntrospectionResponseContext([NotNull] OpenIddictValidationTransaction transaction)
public HandleIntrospectionResponseContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response!;
set => Transaction.Response = value;
}
/// <summary>
/// Gets or sets the token sent to the introspection endpoint.
/// </summary>
public string Token { get; set; }
public string? Token { get; set; }
/// <summary>
/// Gets or sets the token type sent to the introspection endpoint.
/// </summary>
public string TokenType { get; set; }
public string? TokenType { get; set; }
/// <summary>
/// Gets or sets the principal containing the claims resolved from the introspection response.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
}
}
}

102
src/OpenIddict.Validation/OpenIddictValidationEvents.cs

@ -7,7 +7,6 @@
using System;
using System.ComponentModel;
using System.Security.Claims;
using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
@ -25,7 +24,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="BaseContext"/> class.
/// </summary>
protected BaseContext([NotNull] OpenIddictValidationTransaction transaction)
protected BaseContext(OpenIddictValidationTransaction transaction)
=> Transaction = transaction ?? throw new ArgumentNullException(nameof(transaction));
/// <summary>
@ -45,7 +44,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets or sets the issuer address associated with the current transaction, if available.
/// </summary>
public Uri Issuer
public Uri? Issuer
{
get => Transaction.Issuer;
set => Transaction.Issuer = value;
@ -65,24 +64,6 @@ namespace OpenIddict.Validation
/// Gets the OpenIddict validation options.
/// </summary>
public OpenIddictValidationOptions Options => Transaction.Options;
/// <summary>
/// Gets or sets the OpenIddict request or <c>null</c> if it couldn't be extracted.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the OpenIddict response, if applicable.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response;
set => Transaction.Response = value;
}
}
/// <summary>
@ -94,7 +75,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="BaseRequestContext"/> class.
/// </summary>
protected BaseRequestContext([NotNull] OpenIddictValidationTransaction transaction)
protected BaseRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
@ -133,7 +114,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="BaseRequestContext"/> class.
/// </summary>
protected BaseExternalContext([NotNull] OpenIddictValidationTransaction transaction)
protected BaseExternalContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
@ -141,7 +122,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets or sets the address of the external endpoint to communicate with.
/// </summary>
public Uri Address { get; set; }
public Uri? Address { get; set; }
}
/// <summary>
@ -153,7 +134,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="BaseValidatingContext"/> class.
/// </summary>
protected BaseValidatingContext([NotNull] OpenIddictValidationTransaction transaction)
protected BaseValidatingContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
@ -166,17 +147,17 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets or sets the "error" parameter returned to the client application.
/// </summary>
public string Error { get; private set; }
public string? Error { get; private set; }
/// <summary>
/// Gets or sets the "error_description" parameter returned to the client application.
/// </summary>
public string ErrorDescription { get; private set; }
public string? ErrorDescription { get; private set; }
/// <summary>
/// Gets or sets the "error_uri" parameter returned to the client application.
/// </summary>
public string ErrorUri { get; private set; }
public string? ErrorUri { get; private set; }
/// <summary>
/// Rejects the request.
@ -187,7 +168,7 @@ namespace OpenIddict.Validation
/// Rejects the request.
/// </summary>
/// <param name="error">The "error" parameter returned to the client application.</param>
public virtual void Reject(string error)
public virtual void Reject(string? error)
{
Error = error;
@ -199,7 +180,7 @@ namespace OpenIddict.Validation
/// </summary>
/// <param name="error">The "error" parameter returned to the client application.</param>
/// <param name="description">The "error_description" parameter returned to the client application.</param>
public virtual void Reject(string error, string description)
public virtual void Reject(string? error, string? description)
{
Error = error;
ErrorDescription = description;
@ -213,7 +194,7 @@ namespace OpenIddict.Validation
/// <param name="error">The "error" parameter returned to the client application.</param>
/// <param name="description">The "error_description" parameter returned to the client application.</param>
/// <param name="uri">The "error_uri" parameter returned to the client application.</param>
public virtual void Reject(string error, string description, string uri)
public virtual void Reject(string? error, string? description, string? uri)
{
Error = error;
ErrorDescription = description;
@ -231,7 +212,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ProcessRequestContext"/> class.
/// </summary>
public ProcessRequestContext([NotNull] OpenIddictValidationTransaction transaction)
public ProcessRequestContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
@ -245,10 +226,28 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ProcessErrorContext"/> class.
/// </summary>
public ProcessErrorContext([NotNull] OpenIddictValidationTransaction transaction)
public ProcessErrorContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request, or <c>null</c> if it couldn't be extracted.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response!;
set => Transaction.Response = value;
}
}
/// <summary>
@ -259,25 +258,34 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ProcessAuthenticationContext"/> class.
/// </summary>
public ProcessAuthenticationContext([NotNull] OpenIddictValidationTransaction transaction)
public ProcessAuthenticationContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// Gets or sets the token to validate.
/// </summary>
public string Token { get; set; }
public string? Token { get; set; }
/// <summary>
/// Gets or sets the expected type of the token.
/// </summary>
public string TokenType { get; set; }
public string? TokenType { get; set; }
}
/// <summary>
@ -288,10 +296,28 @@ namespace OpenIddict.Validation
/// <summary>
/// Creates a new instance of the <see cref="ProcessChallengeContext"/> class.
/// </summary>
public ProcessChallengeContext([NotNull] OpenIddictValidationTransaction transaction)
public ProcessChallengeContext(OpenIddictValidationTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response!;
set => Transaction.Response = value;
}
}
}
}

7
src/OpenIddict.Validation/OpenIddictValidationExtensions.cs

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging.Abstractions;
@ -30,7 +29,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictValidationBuilder"/>.</returns>
public static OpenIddictValidationBuilder AddValidation([NotNull] this OpenIddictBuilder builder)
public static OpenIddictValidationBuilder AddValidation(this OpenIddictBuilder builder)
{
if (builder == null)
{
@ -81,8 +80,8 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
public static OpenIddictBuilder AddValidation(
[NotNull] this OpenIddictBuilder builder,
[NotNull] Action<OpenIddictValidationBuilder> configuration)
this OpenIddictBuilder builder,
Action<OpenIddictValidationBuilder> configuration)
{
if (builder == null)
{

7
src/OpenIddict.Validation/OpenIddictValidationFactory.cs

@ -5,7 +5,6 @@
*/
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -23,9 +22,9 @@ namespace OpenIddict.Validation
/// Creates a new instance of the <see cref="OpenIddictValidationFactory"/> class.
/// </summary>
public OpenIddictValidationFactory(
[NotNull] IStringLocalizer<OpenIddictResources> localizer,
[NotNull] ILogger<OpenIddictValidationDispatcher> logger,
[NotNull] IOptionsMonitor<OpenIddictValidationOptions> options)
IStringLocalizer<OpenIddictResources> localizer,
ILogger<OpenIddictValidationDispatcher> logger,
IOptionsMonitor<OpenIddictValidationOptions> options)
{
_localizer = localizer;
_logger = logger;

5
src/OpenIddict.Validation/OpenIddictValidationHandler.cs

@ -6,7 +6,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Validation.OpenIddictValidationEvents;
namespace OpenIddict.Validation
@ -23,7 +22,7 @@ namespace OpenIddict.Validation
/// Creates a new event using the specified handler delegate.
/// </summary>
/// <param name="handler">The event handler delegate.</param>
public OpenIddictValidationHandler([NotNull] Func<TContext, ValueTask> handler)
public OpenIddictValidationHandler(Func<TContext, ValueTask> handler)
=> _handler = handler ?? throw new ArgumentNullException(nameof(handler));
/// <summary>
@ -33,7 +32,7 @@ namespace OpenIddict.Validation
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
public ValueTask HandleAsync(TContext context)
=> _handler(context ?? throw new ArgumentNullException(nameof(context)));
}
}

15
src/OpenIddict.Validation/OpenIddictValidationHandlerDescriptor.cs

@ -10,7 +10,6 @@ using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using static OpenIddict.Validation.OpenIddictValidationEvents;
using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -31,7 +30,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets the context type associated with the event.
/// </summary>
public Type ContextType { get; private set; }
public Type ContextType { get; private set; } = default!;
/// <summary>
/// Gets the list of filters responsible of excluding the handler
@ -47,7 +46,7 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets the service descriptor associated with the handler.
/// </summary>
public ServiceDescriptor ServiceDescriptor { get; private set; }
public ServiceDescriptor ServiceDescriptor { get; private set; } = default!;
/// <summary>
/// Gets the type associated with the handler.
@ -68,7 +67,7 @@ namespace OpenIddict.Validation
/// <typeparam name="TContext">The event context type.</typeparam>
public class Builder<TContext> where TContext : BaseContext
{
private ServiceDescriptor _descriptor;
private ServiceDescriptor? _descriptor;
private readonly List<Type> _filterTypes = new List<Type>();
private int _order;
private OpenIddictValidationHandlerType _type;
@ -78,7 +77,7 @@ namespace OpenIddict.Validation
/// </summary>
/// <param name="type">The event handler filter type.</param>
/// <returns>The builder instance, so that calls can be easily chained.</returns>
public Builder<TContext> AddFilter([NotNull] Type type)
public Builder<TContext> AddFilter(Type type)
{
if (type == null)
{
@ -109,7 +108,7 @@ namespace OpenIddict.Validation
/// </summary>
/// <param name="descriptor">The service descriptor.</param>
/// <returns>The builder instance, so that calls can be easily chained.</returns>
public Builder<TContext> SetServiceDescriptor([NotNull] ServiceDescriptor descriptor)
public Builder<TContext> SetServiceDescriptor(ServiceDescriptor descriptor)
{
if (descriptor == null)
{
@ -161,7 +160,7 @@ namespace OpenIddict.Validation
/// </summary>
/// <param name="handler">The handler instance.</param>
/// <returns>The builder instance, so that calls can be easily chained.</returns>
public Builder<TContext> UseInlineHandler([NotNull] Func<TContext, ValueTask> handler)
public Builder<TContext> UseInlineHandler(Func<TContext, ValueTask> handler)
{
if (handler == null)
{
@ -197,7 +196,7 @@ namespace OpenIddict.Validation
/// <typeparam name="THandler">The handler type.</typeparam>
/// <param name="handler">The handler instance.</param>
/// <returns>The builder instance, so that calls can be easily chained.</returns>
public Builder<TContext> UseSingletonHandler<THandler>([NotNull] THandler handler)
public Builder<TContext> UseSingletonHandler<THandler>(THandler handler)
where THandler : IOpenIddictValidationHandler<TContext>
{
if (handler == null)

9
src/OpenIddict.Validation/OpenIddictValidationHandlerFilters.cs

@ -7,7 +7,6 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Validation.OpenIddictValidationEvents;
namespace OpenIddict.Validation
@ -20,7 +19,7 @@ namespace OpenIddict.Validation
/// </summary>
public class RequireAuthorizationEntryValidationEnabled : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{
@ -36,7 +35,7 @@ namespace OpenIddict.Validation
/// </summary>
public class RequireLocalValidation : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{
@ -52,7 +51,7 @@ namespace OpenIddict.Validation
/// </summary>
public class RequireIntrospectionValidation : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{
@ -68,7 +67,7 @@ namespace OpenIddict.Validation
/// </summary>
public class RequireTokenEntryValidationEnabled : IOpenIddictValidationHandlerFilter<BaseContext>
{
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context)
public ValueTask<bool> IsActiveAsync(BaseContext context)
{
if (context == null)
{

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

@ -7,7 +7,6 @@
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.IdentityModel.Tokens;
using static OpenIddict.Abstractions.OpenIddictConstants;
using static OpenIddict.Validation.OpenIddictValidationEvents;
@ -49,14 +48,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationResponseContext context)
{
if (context == null)
{
@ -65,7 +58,7 @@ namespace OpenIddict.Validation
// The issuer returned in the discovery document must exactly match the URL used to access it.
// See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation.
var issuer = (string) context.Response[Metadata.Issuer];
var issuer = (string?) context.Response[Metadata.Issuer];
if (string.IsNullOrEmpty(issuer))
{
context.Reject(
@ -75,7 +68,7 @@ namespace OpenIddict.Validation
return default;
}
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri address))
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri? address))
{
context.Reject(
error: Errors.ServerError,
@ -114,14 +107,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationResponseContext context)
{
if (context == null)
{
@ -130,7 +117,7 @@ namespace OpenIddict.Validation
// 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];
var address = (string?) context.Response[Metadata.JwksUri];
if (string.IsNullOrEmpty(address))
{
context.Reject(
@ -170,21 +157,15 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationResponseContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var address = (string) context.Response[Metadata.IntrospectionEndpoint];
var address = (string?) context.Response[Metadata.IntrospectionEndpoint];
if (!string.IsNullOrEmpty(address) && !Uri.IsWellFormedUriString(address, UriKind.Absolute))
{
context.Reject(
@ -201,7 +182,7 @@ namespace OpenIddict.Validation
{
foreach (var method in methods.GetUnnamedParameters())
{
var value = (string) method;
var value = (string?) method;
if (string.IsNullOrEmpty(value))
{
continue;
@ -230,14 +211,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleCryptographyResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleCryptographyResponseContext context)
{
if (context == null)
{
@ -259,7 +234,7 @@ namespace OpenIddict.Validation
// Note: the "use" parameter is defined as optional by the specification.
// To prevent key swapping attacks, OpenIddict requires that this parameter
// be present and will ignore keys that don't include a "use" parameter.
var use = (string) keys[index][JsonWebKeyParameterNames.Use];
var use = (string?) keys[index][JsonWebKeyParameterNames.Use];
if (string.IsNullOrEmpty(use))
{
continue;
@ -271,21 +246,21 @@ namespace OpenIddict.Validation
continue;
}
var key = (string) keys[index][JsonWebKeyParameterNames.Kty] switch
var key = (string?) keys[index][JsonWebKeyParameterNames.Kty] switch
{
JsonWebAlgorithmsKeyTypes.RSA => new JsonWebKey
{
Kty = JsonWebAlgorithmsKeyTypes.RSA,
E = (string) keys[index][JsonWebKeyParameterNames.E],
N = (string) keys[index][JsonWebKeyParameterNames.N]
E = (string?) keys[index][JsonWebKeyParameterNames.E],
N = (string?) keys[index][JsonWebKeyParameterNames.N]
},
JsonWebAlgorithmsKeyTypes.EllipticCurve => new JsonWebKey
{
Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
Crv = (string) keys[index][JsonWebKeyParameterNames.Crv],
X = (string) keys[index][JsonWebKeyParameterNames.X],
Y = (string) keys[index][JsonWebKeyParameterNames.Y]
Crv = (string?) keys[index][JsonWebKeyParameterNames.Crv],
X = (string?) keys[index][JsonWebKeyParameterNames.X],
Y = (string?) keys[index][JsonWebKeyParameterNames.Y]
},
_ => null
@ -300,15 +275,15 @@ namespace OpenIddict.Validation
return default;
}
key.KeyId = (string) keys[index][JsonWebKeyParameterNames.Kid];
key.X5t = (string) keys[index][JsonWebKeyParameterNames.X5t];
key.X5tS256 = (string) keys[index][JsonWebKeyParameterNames.X5tS256];
key.KeyId = (string?) keys[index][JsonWebKeyParameterNames.Kid];
key.X5t = (string?) keys[index][JsonWebKeyParameterNames.X5t];
key.X5tS256 = (string?) keys[index][JsonWebKeyParameterNames.X5tS256];
if (keys[index].TryGetNamedParameter(JsonWebKeyParameterNames.X5c, out var chain))
{
foreach (var certificate in chain.GetNamedParameters())
{
var value = (string) certificate.Value;
var value = (string?) certificate.Value;
if (string.IsNullOrEmpty(value))
{
context.Reject(

79
src/OpenIddict.Validation/OpenIddictValidationHandlers.Introspection.cs

@ -10,7 +10,6 @@ using System.Globalization;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.IdentityModel.JsonWebTokens;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
@ -55,14 +54,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] PrepareIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(PrepareIntrospectionRequestContext context)
{
if (context == null)
{
@ -91,14 +84,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] PrepareIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(PrepareIntrospectionRequestContext context)
{
if (context == null)
{
@ -127,14 +114,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionResponseContext context)
{
if (context == null)
{
@ -185,14 +166,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionResponseContext context)
{
if (context == null)
{
@ -306,14 +281,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionResponseContext context)
{
if (context == null)
{
@ -322,10 +291,10 @@ namespace OpenIddict.Validation
// The issuer claim is optional. If it's not null or empty, validate it to
// ensure it matches the issuer registered in the server configuration.
var issuer = (string) context.Response[Claims.Issuer];
var issuer = (string?) context.Response[Claims.Issuer];
if (!string.IsNullOrEmpty(issuer))
{
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri uri))
if (!Uri.TryCreate(issuer, UriKind.Absolute, out Uri? uri))
{
context.Reject(
error: Errors.ServerError,
@ -363,14 +332,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionResponseContext context)
{
if (context == null)
{
@ -382,7 +345,7 @@ namespace OpenIddict.Validation
// introspected token is of the expected type and prevent token substitution attacks.
if (!string.IsNullOrEmpty(context.TokenType))
{
var usage = (string) context.Response[Claims.TokenUsage];
var usage = (string?) context.Response[Claims.TokenUsage];
if (!string.IsNullOrEmpty(usage) &&
!string.Equals(usage, context.TokenType, StringComparison.OrdinalIgnoreCase))
{
@ -413,14 +376,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionResponseContext context)
{
if (context == null)
{
@ -437,7 +394,7 @@ namespace OpenIddict.Validation
// Resolve the issuer that will be attached to the claims created by this handler.
// Note: at this stage, the optional issuer extracted from the response is assumed
// to be valid, as it is guarded against unknown values by the ValidateIssuer handler.
var issuer = (string) context.Response[Claims.Issuer] ?? context.Issuer?.AbsoluteUri ?? ClaimsIdentity.DefaultIssuer;
var issuer = (string?) context.Response[Claims.Issuer] ?? context.Issuer?.AbsoluteUri ?? ClaimsIdentity.DefaultIssuer;
foreach (var parameter in context.Response.GetParameters())
{

151
src/OpenIddict.Validation/OpenIddictValidationHandlers.cs

@ -7,11 +7,11 @@
using System;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions;
@ -66,14 +66,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -110,7 +104,7 @@ namespace OpenIddict.Validation
public ValidateReferenceTokenIdentifier() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1138));
public ValidateReferenceTokenIdentifier([NotNull] IOpenIddictTokenManager tokenManager)
public ValidateReferenceTokenIdentifier(IOpenIddictTokenManager tokenManager)
=> _tokenManager = tokenManager;
/// <summary>
@ -125,7 +119,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -187,14 +182,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -295,7 +284,7 @@ namespace OpenIddict.Validation
{
private readonly OpenIddictValidationService _service;
public IntrospectToken([NotNull] OpenIddictValidationService service)
public IntrospectToken(OpenIddictValidationService service)
=> _service = service;
/// <summary>
@ -309,14 +298,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -329,11 +312,13 @@ namespace OpenIddict.Validation
return;
}
Debug.Assert(!string.IsNullOrEmpty(context.Token), SR.GetResourceString(SR.ID5010));
var configuration = await context.Options.ConfigurationManager.GetConfigurationAsync(default) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1139));
if (string.IsNullOrEmpty(configuration.IntrospectionEndpoint) ||
!Uri.TryCreate(configuration.IntrospectionEndpoint, UriKind.Absolute, out Uri address) ||
!Uri.TryCreate(configuration.IntrospectionEndpoint, UriKind.Absolute, out Uri? address) ||
!address.IsWellFormedOriginalString())
{
context.Reject(
@ -385,14 +370,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -436,14 +415,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -540,7 +513,7 @@ namespace OpenIddict.Validation
public RestoreReferenceTokenProperties() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1138));
public RestoreReferenceTokenProperties([NotNull] IOpenIddictTokenManager tokenManager)
public RestoreReferenceTokenProperties(IOpenIddictTokenManager tokenManager)
=> _tokenManager = tokenManager;
/// <summary>
@ -555,7 +528,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -567,12 +541,13 @@ namespace OpenIddict.Validation
return;
}
if (!context.Transaction.Properties.TryGetValue(Properties.ReferenceTokenIdentifier, out var identifier))
var identifier = context.Transaction.GetProperty<string>(Properties.ReferenceTokenIdentifier);
if (string.IsNullOrEmpty(identifier))
{
return;
}
var token = await _tokenManager.FindByIdAsync((string) identifier);
var token = await _tokenManager.FindByIdAsync(identifier);
if (token == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1020));
@ -603,14 +578,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -663,20 +632,16 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
var date = context.Principal.GetExpirationDate();
if (date.HasValue && date.Value < DateTimeOffset.UtcNow)
{
@ -709,20 +674,16 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// If no explicit audience has been configured,
// skip the default audience validation.
if (context.Options.Audiences.Count == 0)
@ -770,7 +731,7 @@ namespace OpenIddict.Validation
public ValidateTokenEntry() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1138));
public ValidateTokenEntry([NotNull] IOpenIddictTokenManager tokenManager)
public ValidateTokenEntry(IOpenIddictTokenManager tokenManager)
=> _tokenManager = tokenManager;
/// <summary>
@ -785,13 +746,16 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
var identifier = context.Principal.GetTokenId();
if (string.IsNullOrEmpty(identifier))
{
@ -830,7 +794,7 @@ namespace OpenIddict.Validation
public ValidateAuthorizationEntry() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1141));
public ValidateAuthorizationEntry([NotNull] IOpenIddictAuthorizationManager authorizationManager)
public ValidateAuthorizationEntry(IOpenIddictAuthorizationManager authorizationManager)
=> _authorizationManager = authorizationManager;
/// <summary>
@ -845,13 +809,16 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
public async ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
var identifier = context.Principal.GetAuthorizationId();
if (string.IsNullOrEmpty(identifier))
{
@ -887,14 +854,8 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessChallengeContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessChallengeContext context)
{
if (context == null)
{
@ -917,7 +878,7 @@ namespace OpenIddict.Validation
// to inform the client that the user is not allowed to perform the requested action.
var notification = context.Transaction.GetProperty<ProcessAuthenticationContext>(
typeof(ProcessAuthenticationContext).FullName);
typeof(ProcessAuthenticationContext).FullName!);
if (!string.IsNullOrEmpty(notification?.Error))
{
@ -951,26 +912,20 @@ namespace OpenIddict.Validation
.SetType(OpenIddictValidationHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (!string.IsNullOrEmpty(context.Response.Error))
if (!string.IsNullOrEmpty(context.Transaction.Response?.Error))
{
context.Reject(
error: context.Response.Error,
description: context.Response.ErrorDescription,
uri: context.Response.ErrorUri);
error: context.Transaction.Response.Error,
description: context.Transaction.Response.ErrorDescription,
uri: context.Transaction.Response.ErrorUri);
return default;
}

9
src/OpenIddict.Validation/OpenIddictValidationHelpers.cs

@ -5,7 +5,6 @@
*/
using System;
using JetBrains.Annotations;
using SR = OpenIddict.Abstractions.OpenIddictResources;
namespace OpenIddict.Validation
@ -22,8 +21,8 @@ namespace OpenIddict.Validation
/// <param name="transaction">The validation transaction.</param>
/// <param name="name">The property name.</param>
/// <returns>The property value or <c>null</c> if it couldn't be found.</returns>
public static TProperty GetProperty<TProperty>(
[NotNull] this OpenIddictValidationTransaction transaction, [NotNull] string name) where TProperty : class
public static TProperty? GetProperty<TProperty>(
this OpenIddictValidationTransaction transaction, string name) where TProperty : class
{
if (transaction == null)
{
@ -52,8 +51,8 @@ namespace OpenIddict.Validation
/// <param name="value">The property value.</param>
/// <returns>The validation transaction, so that calls can be easily chained.</returns>
public static OpenIddictValidationTransaction SetProperty<TProperty>(
[NotNull] this OpenIddictValidationTransaction transaction,
[NotNull] string name, [CanBeNull] TProperty value) where TProperty : class
this OpenIddictValidationTransaction transaction,
string name, TProperty? value) where TProperty : class
{
if (transaction == null)
{

12
src/OpenIddict.Validation/OpenIddictValidationOptions.cs

@ -60,12 +60,12 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets or sets the client identifier sent to the authorization server when using remote validation.
/// </summary>
public string ClientId { get; set; }
public string? ClientId { get; set; }
/// <summary>
/// Gets or sets the client secret sent to the authorization server when using remote validation.
/// </summary>
public string ClientSecret { get; set; }
public string? ClientSecret { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether a database call is made
@ -86,24 +86,24 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets or sets the absolute URL of the OAuth 2.0/OpenID Connect server.
/// </summary>
public Uri Issuer { get; set; }
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.
/// </summary>
public Uri MetadataAddress { get; set; }
public Uri? MetadataAddress { get; set; }
/// <summary>
/// Gets or sets the OAuth 2.0/OpenID Connect static server configuration, if applicable.
/// </summary>
public OpenIdConnectConfiguration Configuration { get; set; }
public OpenIdConnectConfiguration? Configuration { get; set; }
/// <summary>
/// Gets or sets the configuration manager used to retrieve
/// and cache the OAuth 2.0/OpenID Connect server configuration.
/// </summary>
public IConfigurationManager<OpenIdConnectConfiguration> ConfigurationManager { get; set; }
public IConfigurationManager<OpenIdConnectConfiguration> ConfigurationManager { get; set; } = default!;
/// <summary>
/// Gets the intended audiences of this resource server.

5
src/OpenIddict.Validation/OpenIddictValidationRetriever.cs

@ -7,7 +7,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -22,7 +21,7 @@ namespace OpenIddict.Validation
/// Creates a new instance of the <see cref="OpenIddictValidationRetriever"/> class.
/// </summary>
/// <param name="service">The validation service.</param>
public OpenIddictValidationRetriever([NotNull] OpenIddictValidationService service)
public OpenIddictValidationRetriever(OpenIddictValidationService service)
=> _service = service;
/// <summary>
@ -39,7 +38,7 @@ namespace OpenIddict.Validation
throw new ArgumentException(SR.GetResourceString(SR.ID1142), nameof(address));
}
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri uri) || !uri.IsWellFormedOriginalString())
if (!Uri.TryCreate(address, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{
throw new ArgumentException(SR.GetResourceString(SR.ID1143), nameof(address));
}

29
src/OpenIddict.Validation/OpenIddictValidationService.cs

@ -5,10 +5,10 @@
*/
using System;
using System.Diagnostics;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
@ -27,7 +27,7 @@ namespace OpenIddict.Validation
/// Creates a new instance of the <see cref="OpenIddictValidationService"/> class.
/// </summary>
/// <param name="provider">The service provider.</param>
public OpenIddictValidationService([NotNull] IServiceProvider provider)
public OpenIddictValidationService(IServiceProvider provider)
=> _provider = provider;
/// <summary>
@ -36,8 +36,7 @@ namespace OpenIddict.Validation
/// <param name="address">The address 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>
public async ValueTask<OpenIdConnectConfiguration> GetConfigurationAsync(
[NotNull] Uri address, CancellationToken cancellationToken = default)
public async ValueTask<OpenIdConnectConfiguration> GetConfigurationAsync(Uri address, CancellationToken cancellationToken = default)
{
if (address == null)
{
@ -132,6 +131,8 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
Debug.Assert(context.Response != null, SR.GetResourceString(SR.ID5007));
return context.Response;
}
@ -176,8 +177,7 @@ namespace OpenIddict.Validation
/// <param name="address">The address 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>
public async ValueTask<JsonWebKeySet> GetSecurityKeysAsync(
[NotNull] Uri address, CancellationToken cancellationToken = default)
public async ValueTask<JsonWebKeySet> GetSecurityKeysAsync(Uri address, CancellationToken cancellationToken = default)
{
if (address == null)
{
@ -273,6 +273,8 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
Debug.Assert(context.Response != null, SR.GetResourceString(SR.ID5007));
return context.Response;
}
@ -318,8 +320,7 @@ namespace OpenIddict.Validation
/// <param name="token">The token to introspect.</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>
public ValueTask<ClaimsPrincipal> IntrospectTokenAsync(
[NotNull] Uri address, [NotNull] string token, CancellationToken cancellationToken = default)
public ValueTask<ClaimsPrincipal> IntrospectTokenAsync(Uri address, string token, CancellationToken cancellationToken = default)
=> IntrospectTokenAsync(address, token, type: null, cancellationToken);
/// <summary>
@ -331,8 +332,7 @@ namespace OpenIddict.Validation
/// <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>
public async ValueTask<ClaimsPrincipal> IntrospectTokenAsync(
[NotNull] Uri address, [NotNull] string token,
[CanBeNull] string type, CancellationToken cancellationToken = default)
Uri address, string token, string? type, CancellationToken cancellationToken = default)
{
if (address == null)
{
@ -434,6 +434,8 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
Debug.Assert(context.Response != null, SR.GetResourceString(SR.ID5007));
return context.Response;
}
@ -456,6 +458,8 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
return context.Principal;
}
}
@ -480,8 +484,7 @@ namespace OpenIddict.Validation
/// <param name="token">The access token to validate.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>The principal containing the claims extracted from the token.</returns>
public async ValueTask<ClaimsPrincipal> ValidateAccessTokenAsync(
[NotNull] string token, CancellationToken cancellationToken = default)
public async ValueTask<ClaimsPrincipal> ValidateAccessTokenAsync(string token, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(token))
{
@ -518,6 +521,8 @@ namespace OpenIddict.Validation
context.Error, context.ErrorDescription, context.ErrorUri);
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
return context.Principal;
}

16
src/OpenIddict.Validation/OpenIddictValidationTransaction.cs

@ -25,37 +25,37 @@ namespace OpenIddict.Validation
/// <summary>
/// Gets or sets the issuer address associated with the current transaction, if available.
/// </summary>
public Uri Issuer { get; set; }
public Uri? Issuer { get; set; }
/// <summary>
/// Gets or sets the localizer associated with the current request.
/// </summary>
public IStringLocalizer Localizer { get; set; }
public IStringLocalizer Localizer { get; set; } = default!;
/// <summary>
/// Gets or sets the logger associated with the current request.
/// </summary>
public ILogger Logger { get; set; }
public ILogger Logger { get; set; } = default!;
/// <summary>
/// Gets or sets the options associated with the current request.
/// </summary>
public OpenIddictValidationOptions Options { get; set; }
public OpenIddictValidationOptions Options { get; set; } = default!;
/// <summary>
/// Gets the additional properties associated with the current request.
/// </summary>
public IDictionary<string, object> Properties { get; }
= new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public IDictionary<string, object?> Properties { get; }
= new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Gets or sets the current OpenID Connect request.
/// </summary>
public OpenIddictRequest Request { get; set; }
public OpenIddictRequest? Request { get; set; }
/// <summary>
/// Gets or sets the current OpenID Connect response being returned.
/// </summary>
public OpenIddictResponse Response { get; set; }
public OpenIddictResponse? Response { get; set; }
}
}

Loading…
Cancel
Save