Browse Source

Add nullable annotations to OpenIddict.Server, OpenIddict.Server.AspNetCore, OpenIddict.Server.Owin and OpenIddict.Server.DataProtection

pull/1038/head
Kévin Chalet 6 years ago
parent
commit
de5485ceee
  1. 11
      Directory.Packages.props
  2. 5
      src/OpenIddict.Server.AspNetCore/OpenIddict.Server.AspNetCore.csproj
  3. 15
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreBuilder.cs
  4. 31
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreConfiguration.cs
  5. 6
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreExtensions.cs
  6. 2
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreFeature.cs
  7. 50
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
  8. 43
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlerFilters.cs
  9. 85
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Authentication.cs
  10. 57
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs
  11. 289
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs
  12. 13
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHelpers.cs
  13. 5
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreOptions.cs
  14. 5
      src/OpenIddict.Server.DataProtection/IOpenIddictServerDataProtectionFormatter.cs
  15. 5
      src/OpenIddict.Server.DataProtection/OpenIddict.Server.DataProtection.csproj
  16. 13
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionBuilder.cs
  17. 7
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConfiguration.cs
  18. 6
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionExtensions.cs
  19. 13
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs
  20. 21
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlerFilters.cs
  21. 100
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
  22. 2
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionOptions.cs
  23. 1
      src/OpenIddict.Server.Owin/OpenIddict.Server.Owin.csproj
  24. 15
      src/OpenIddict.Server.Owin/OpenIddictServerOwinBuilder.cs
  25. 5
      src/OpenIddict.Server.Owin/OpenIddictServerOwinConfiguration.cs
  26. 6
      src/OpenIddict.Server.Owin/OpenIddictServerOwinExtensions.cs
  27. 38
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs
  28. 39
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlerFilters.cs
  29. 85
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Authentication.cs
  30. 57
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs
  31. 265
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs
  32. 15
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHelpers.cs
  33. 9
      src/OpenIddict.Server.Owin/OpenIddictServerOwinMiddleware.cs
  34. 5
      src/OpenIddict.Server.Owin/OpenIddictServerOwinMiddlewareFactory.cs
  35. 5
      src/OpenIddict.Server.Owin/OpenIddictServerOwinOptions.cs
  36. 3
      src/OpenIddict.Server/IOpenIddictServerDispatcher.cs
  37. 3
      src/OpenIddict.Server/IOpenIddictServerHandler.cs
  38. 3
      src/OpenIddict.Server/IOpenIddictServerHandlerFilter.cs
  39. 1
      src/OpenIddict.Server/OpenIddict.Server.csproj
  40. 133
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  41. 5
      src/OpenIddict.Server/OpenIddictServerConfiguration.cs
  42. 9
      src/OpenIddict.Server/OpenIddictServerDispatcher.cs
  43. 73
      src/OpenIddict.Server/OpenIddictServerEvents.Authentication.cs
  44. 114
      src/OpenIddict.Server/OpenIddictServerEvents.Device.cs
  45. 136
      src/OpenIddict.Server/OpenIddictServerEvents.Discovery.cs
  46. 61
      src/OpenIddict.Server/OpenIddictServerEvents.Exchange.cs
  47. 77
      src/OpenIddict.Server/OpenIddictServerEvents.Introspection.cs
  48. 63
      src/OpenIddict.Server/OpenIddictServerEvents.Revocation.cs
  49. 63
      src/OpenIddict.Server/OpenIddictServerEvents.Session.cs
  50. 78
      src/OpenIddict.Server/OpenIddictServerEvents.Userinfo.cs
  51. 162
      src/OpenIddict.Server/OpenIddictServerEvents.cs
  52. 7
      src/OpenIddict.Server/OpenIddictServerExtensions.cs
  53. 7
      src/OpenIddict.Server/OpenIddictServerFactory.cs
  54. 5
      src/OpenIddict.Server/OpenIddictServerHandler.cs
  55. 15
      src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs
  56. 65
      src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs
  57. 302
      src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
  58. 224
      src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
  59. 223
      src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs
  60. 321
      src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
  61. 228
      src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
  62. 215
      src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
  63. 100
      src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
  64. 112
      src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs
  65. 723
      src/OpenIddict.Server/OpenIddictServerHandlers.cs
  66. 9
      src/OpenIddict.Server/OpenIddictServerHelpers.cs
  67. 2
      src/OpenIddict.Server/OpenIddictServerOptions.cs
  68. 16
      src/OpenIddict.Server/OpenIddictServerTransaction.cs
  69. 12
      test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

11
Directory.Packages.props

@ -26,10 +26,8 @@
<ItemGroup <ItemGroup
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETFramework') Or Condition=" ('$(TargetFrameworkIdentifier)' == '.NETFramework') Or
('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.0')) And ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '2.1'))) Or
$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0'))) Or ('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '2.0'))) ">
('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.0')) And
$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '2.1'))) ">
<PackageVersion Include="Microsoft.AspNetCore.Authentication" Version="2.1.2" /> <PackageVersion Include="Microsoft.AspNetCore.Authentication" Version="2.1.2" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="2.1.2" /> <PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="2.1.2" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection" Version="2.1.1" /> <PackageVersion Include="Microsoft.AspNetCore.DataProtection" Version="2.1.1" />
@ -51,9 +49,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup <ItemGroup
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.0')) And Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '3.1'))) Or
$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '5.0'))) Or ('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '2.1'))) ">
('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.1'))) ">
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.6" /> <PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.6" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection" Version="3.1.6" /> <PackageVersion Include="Microsoft.AspNetCore.DataProtection" Version="3.1.6" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.6" /> <PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.6" />

5
src/OpenIddict.Server.AspNetCore/OpenIddict.Server.AspNetCore.csproj

@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1</TargetFrameworks> <TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@ -14,12 +15,12 @@
</ItemGroup> </ItemGroup>
<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" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
<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" /> <PackageReference Include="Microsoft.AspNetCore.Authentication" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" /> <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" />

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

@ -6,7 +6,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using JetBrains.Annotations;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
@ -25,7 +24,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictServerAspNetCoreBuilder"/>. /// Initializes a new instance of <see cref="OpenIddictServerAspNetCoreBuilder"/>.
/// </summary> /// </summary>
/// <param name="services">The services collection.</param> /// <param name="services">The services collection.</param>
public OpenIddictServerAspNetCoreBuilder([NotNull] IServiceCollection services) public OpenIddictServerAspNetCoreBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services)); => Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary> /// <summary>
@ -40,7 +39,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param> /// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks> /// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder Configure([NotNull] Action<OpenIddictServerAspNetCoreOptions> configuration) public OpenIddictServerAspNetCoreBuilder Configure(Action<OpenIddictServerAspNetCoreOptions> configuration)
{ {
if (configuration == null) if (configuration == null)
{ {
@ -155,7 +154,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="realm">The issuer address.</param> /// <param name="realm">The issuer address.</param>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder SetRealm([NotNull] string realm) public OpenIddictServerAspNetCoreBuilder SetRealm(string realm)
{ {
if (string.IsNullOrEmpty(realm)) if (string.IsNullOrEmpty(realm))
{ {
@ -171,7 +170,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="policy">The caching policy.</param> /// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder SetAuthorizationEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy) public OpenIddictServerAspNetCoreBuilder SetAuthorizationEndpointCachingPolicy(DistributedCacheEntryOptions policy)
{ {
if (policy == null) if (policy == null)
{ {
@ -187,7 +186,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="policy">The caching policy.</param> /// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public OpenIddictServerAspNetCoreBuilder SetLogoutEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy) public OpenIddictServerAspNetCoreBuilder SetLogoutEndpointCachingPolicy(DistributedCacheEntryOptions policy)
{ {
if (policy == null) if (policy == null)
{ {
@ -203,7 +202,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param> /// <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> /// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj); public override bool Equals(object? obj) => base.Equals(obj);
/// <summary> /// <summary>
/// Serves as the default hash function. /// Serves as the default hash function.
@ -217,6 +216,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <returns>A string that represents the current object.</returns> /// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString(); public override string? ToString() => base.ToString();
} }
} }

31
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreConfiguration.cs

@ -6,7 +6,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using SR = OpenIddict.Abstractions.OpenIddictResources; using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -25,7 +24,7 @@ namespace OpenIddict.Server.AspNetCore
/// Registers the OpenIddict server handler in the global authentication options. /// Registers the OpenIddict server handler in the global authentication options.
/// </summary> /// </summary>
/// <param name="options">The options instance to initialize.</param> /// <param name="options">The options instance to initialize.</param>
public void Configure([NotNull] AuthenticationOptions options) public void Configure(AuthenticationOptions options)
{ {
if (options == null) if (options == null)
{ {
@ -43,7 +42,7 @@ namespace OpenIddict.Server.AspNetCore
OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, displayName: null); OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, displayName: null);
} }
public void Configure([NotNull] OpenIddictServerOptions options) public void Configure(OpenIddictServerOptions options)
{ {
if (options == null) if (options == null)
{ {
@ -59,24 +58,13 @@ namespace OpenIddict.Server.AspNetCore
/// </summary> /// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param> /// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</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) if (options == null)
{ {
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
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) || !map.TryGetValue(scheme, out var builder))
{
return true;
}
return builder.HandlerType != typeof(OpenIddictServerAspNetCoreHandler);
}
if (!TryValidate(options.SchemeMap, options.DefaultAuthenticateScheme) || if (!TryValidate(options.SchemeMap, options.DefaultAuthenticateScheme) ||
!TryValidate(options.SchemeMap, options.DefaultChallengeScheme) || !TryValidate(options.SchemeMap, options.DefaultChallengeScheme) ||
!TryValidate(options.SchemeMap, options.DefaultForbidScheme) || !TryValidate(options.SchemeMap, options.DefaultForbidScheme) ||
@ -86,6 +74,17 @@ namespace OpenIddict.Server.AspNetCore
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1108)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1108));
} }
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) || !map.TryGetValue(scheme, out var builder))
{
return true;
}
return builder.HandlerType != typeof(OpenIddictServerAspNetCoreHandler);
}
} }
/// <summary> /// <summary>
@ -94,7 +93,7 @@ namespace OpenIddict.Server.AspNetCore
/// </summary> /// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param> /// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param> /// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictServerAspNetCoreOptions options) public void PostConfigure(string name, OpenIddictServerAspNetCoreOptions options)
{ {
if (options == null) if (options == null)
{ {

6
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreExtensions.cs

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

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

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

50
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs

@ -6,10 +6,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -36,18 +36,19 @@ namespace OpenIddict.Server.AspNetCore
/// Creates a new instance of the <see cref="OpenIddictServerAspNetCoreHandler"/> class. /// Creates a new instance of the <see cref="OpenIddictServerAspNetCoreHandler"/> class.
/// </summary> /// </summary>
public OpenIddictServerAspNetCoreHandler( public OpenIddictServerAspNetCoreHandler(
[NotNull] IOpenIddictServerDispatcher dispatcher, IOpenIddictServerDispatcher dispatcher,
[NotNull] IOpenIddictServerFactory factory, IOpenIddictServerFactory factory,
[NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options, IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options,
[NotNull] ILoggerFactory logger, ILoggerFactory logger,
[NotNull] UrlEncoder encoder, UrlEncoder encoder,
[NotNull] ISystemClock clock) ISystemClock clock)
: base(options, logger, encoder, clock) : base(options, logger, encoder, clock)
{ {
_dispatcher = dispatcher; _dispatcher = dispatcher;
_factory = factory; _factory = factory;
} }
/// <inheritdoc/>
public async Task<bool> HandleRequestAsync() public async Task<bool> HandleRequestAsync()
{ {
// Note: the transaction may be already attached when replaying an ASP.NET Core request // Note: the transaction may be already attached when replaying an ASP.NET Core request
@ -57,7 +58,7 @@ namespace OpenIddict.Server.AspNetCore
{ {
// Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers. // Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers.
transaction = await _factory.CreateTransactionAsync(); 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 server transaction to the ASP.NET Core features // Attach the OpenIddict server transaction to the ASP.NET Core features
// so that it can retrieved while performing sign-in/sign-out operations. // so that it can retrieved while performing sign-in/sign-out operations.
@ -107,6 +108,7 @@ namespace OpenIddict.Server.AspNetCore
return false; return false;
} }
/// <inheritdoc/>
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{ {
var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ?? var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ??
@ -115,7 +117,7 @@ namespace OpenIddict.Server.AspNetCore
// Note: in many cases, the authentication token was already validated by the time this action is called // 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, // (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. // 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) if (context == null)
{ {
context = new ProcessAuthenticationContext(transaction); context = new ProcessAuthenticationContext(transaction);
@ -123,7 +125,7 @@ namespace OpenIddict.Server.AspNetCore
// Store the context object in the transaction so it can be later retrieved by handlers // 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. // 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) if (context.IsRequestHandled || context.IsRequestSkipped)
@ -141,7 +143,7 @@ namespace OpenIddict.Server.AspNetCore
return AuthenticateResult.NoResult(); return AuthenticateResult.NoResult();
} }
var properties = new AuthenticationProperties(new Dictionary<string, string> var properties = new AuthenticationProperties(new Dictionary<string, string?>
{ {
[OpenIddictServerAspNetCoreConstants.Properties.Error] = context.Error, [OpenIddictServerAspNetCoreConstants.Properties.Error] = context.Error,
[OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = context.ErrorDescription, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = context.ErrorDescription,
@ -153,14 +155,18 @@ namespace OpenIddict.Server.AspNetCore
else else
{ {
// Store the token to allow any ASP.NET Core component (e.g a controller) 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). // to retrieve it (e.g to make an API request to another application).
var properties = new AuthenticationProperties(); var properties = new AuthenticationProperties();
properties.StoreTokens(new[] properties.StoreTokens(new[]
{ {
new AuthenticationToken new AuthenticationToken
{ {
Name = context.TokenType, Name = context.Principal.GetTokenType(),
Value = context.Token Value = context.Token
} }
}); });
@ -171,12 +177,13 @@ namespace OpenIddict.Server.AspNetCore
} }
} }
protected override async Task HandleChallengeAsync([CanBeNull] AuthenticationProperties properties) /// <inheritdoc/>
protected override async Task HandleChallengeAsync(AuthenticationProperties? properties)
{ {
var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ?? var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
transaction.Properties[typeof(AuthenticationProperties).FullName] = properties ?? new AuthenticationProperties(); transaction.Properties[typeof(AuthenticationProperties).FullName!] = properties ?? new AuthenticationProperties();
var context = new ProcessChallengeContext(transaction) var context = new ProcessChallengeContext(transaction)
{ {
@ -213,10 +220,12 @@ namespace OpenIddict.Server.AspNetCore
} }
} }
protected override Task HandleForbiddenAsync([CanBeNull] AuthenticationProperties properties) /// <inheritdoc/>
protected override Task HandleForbiddenAsync(AuthenticationProperties? properties)
=> HandleChallengeAsync(properties); => HandleChallengeAsync(properties);
public async Task SignInAsync([NotNull] ClaimsPrincipal user, [CanBeNull] AuthenticationProperties properties) /// <inheritdoc/>
public async Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties)
{ {
if (user == null) if (user == null)
{ {
@ -226,7 +235,7 @@ namespace OpenIddict.Server.AspNetCore
var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ?? var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
transaction.Properties[typeof(AuthenticationProperties).FullName] = properties ?? new AuthenticationProperties(); transaction.Properties[typeof(AuthenticationProperties).FullName!] = properties ?? new AuthenticationProperties();
var context = new ProcessSignInContext(transaction) var context = new ProcessSignInContext(transaction)
{ {
@ -264,7 +273,8 @@ namespace OpenIddict.Server.AspNetCore
} }
} }
public async Task SignOutAsync([CanBeNull] AuthenticationProperties properties) /// <inheritdoc/>
public async Task SignOutAsync(AuthenticationProperties? properties)
{ {
var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ?? var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
@ -274,7 +284,7 @@ namespace OpenIddict.Server.AspNetCore
Response = new OpenIddictResponse() Response = new OpenIddictResponse()
}; };
transaction.Properties[typeof(AuthenticationProperties).FullName] = properties ?? new AuthenticationProperties(); transaction.Properties[typeof(AuthenticationProperties).FullName!] = properties ?? new AuthenticationProperties();
await _dispatcher.DispatchAsync(context); await _dispatcher.DispatchAsync(context);

43
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlerFilters.cs

@ -7,7 +7,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.OpenIddictServerEvents;
@ -27,10 +26,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireAuthorizationEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireAuthorizationEndpointCachingEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -49,10 +48,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireAuthorizationEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireAuthorizationEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -70,10 +69,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireErrorPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireErrorPassthroughEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -89,7 +88,7 @@ namespace OpenIddict.Server.AspNetCore
/// </summary> /// </summary>
public class RequireHttpRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireHttpRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -107,10 +106,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireLogoutEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireLogoutEndpointCachingEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -129,10 +128,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireLogoutEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireLogoutEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -150,10 +149,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireTransportSecurityRequirementEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireTransportSecurityRequirementEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -171,10 +170,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireStatusCodePagesIntegrationEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireStatusCodePagesIntegrationEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -193,10 +192,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireTokenEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireTokenEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -215,10 +214,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireUserinfoEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireUserinfoEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -237,10 +236,10 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public RequireVerificationEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public RequireVerificationEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {

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

@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
@ -15,7 +16,6 @@ using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
@ -72,7 +72,7 @@ namespace OpenIddict.Server.AspNetCore
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache) public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -87,20 +87,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
/// </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] ExtractAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// If a request_id parameter can be found in the authorization request, // If a request_id parameter can be found in the authorization request,
// restore the complete authorization request from the distributed cache. // restore the complete authorization request from the distributed cache.
@ -173,8 +169,8 @@ namespace OpenIddict.Server.AspNetCore
public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public CacheRequestParameters( public CacheRequestParameters(
[NotNull] IDistributedCache cache, IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
{ {
_cache = cache; _cache = cache;
_options = options; _options = options;
@ -192,20 +188,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
/// </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] ExtractAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetHttpRequest(); var request = context.Transaction.GetHttpRequest();
@ -285,7 +277,7 @@ namespace OpenIddict.Server.AspNetCore
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache) public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -300,14 +292,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -337,7 +323,7 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly HtmlEncoder _encoder; private readonly HtmlEncoder _encoder;
public ProcessFormPostResponse([NotNull] HtmlEncoder encoder) public ProcessFormPostResponse(HtmlEncoder encoder)
=> _encoder = encoder; => _encoder = encoder;
/// <summary> /// <summary>
@ -351,14 +337,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -398,9 +378,10 @@ namespace OpenIddict.Server.AspNetCore
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
writer.WriteLine($@"<input type=""hidden"" name=""{_encoder.Encode(key)}"" value=""{_encoder.Encode(value)}"" />"); writer.WriteLine($@"<input type=""hidden"" name=""{_encoder.Encode(key)}"" value=""{_encoder.Encode(value)}"" />");
@ -446,14 +427,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -483,9 +458,10 @@ namespace OpenIddict.Server.AspNetCore
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
location = QueryHelpers.AddQueryString(location, key, value); location = QueryHelpers.AddQueryString(location, key, value);
@ -515,14 +491,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -552,9 +522,10 @@ namespace OpenIddict.Server.AspNetCore
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
builder.Append(Contains(builder, '#') ? '&' : '#') builder.Append(Contains(builder, '#') ? '&' : '#')

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

@ -7,12 +7,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
@ -69,7 +69,7 @@ namespace OpenIddict.Server.AspNetCore
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache) public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -84,20 +84,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
/// </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] ExtractLogoutRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// If a request_id parameter can be found in the logout request, // If a request_id parameter can be found in the logout request,
// restore the complete logout request from the distributed cache. // restore the complete logout request from the distributed cache.
@ -170,8 +166,8 @@ namespace OpenIddict.Server.AspNetCore
public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public CacheRequestParameters( public CacheRequestParameters(
[NotNull] IDistributedCache cache, IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
{ {
_cache = cache; _cache = cache;
_options = options; _options = options;
@ -189,20 +185,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
/// </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] ExtractLogoutRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetHttpRequest(); var request = context.Transaction.GetHttpRequest();
@ -282,7 +274,7 @@ namespace OpenIddict.Server.AspNetCore
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache) public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -297,14 +289,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyLogoutResponseContext context)
/// </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] ApplyLogoutResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -343,14 +329,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyLogoutResponseContext context)
/// </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] ApplyLogoutResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -379,9 +359,10 @@ namespace OpenIddict.Server.AspNetCore
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
location = QueryHelpers.AddQueryString(location, key, value); location = QueryHelpers.AddQueryString(location, key, value);

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

@ -8,13 +8,13 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
@ -84,14 +84,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessRequestContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -192,14 +186,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessRequestContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -230,7 +218,7 @@ namespace OpenIddict.Server.AspNetCore
return default; 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()) !issuer.IsWellFormedOriginalString())
{ {
context.Reject( context.Reject(
@ -264,14 +252,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessRequestContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -323,21 +305,15 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessChallengeContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); 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) if (properties != null)
{ {
context.Response.Error = properties.GetString(Properties.Error); context.Response.Error = properties.GetString(Properties.Error);
@ -367,21 +343,17 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName); Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties == null) if (properties == null)
{ {
return default; return default;
@ -390,7 +362,7 @@ namespace OpenIddict.Server.AspNetCore
foreach (var parameter in properties.Parameters) foreach (var parameter in properties.Parameters)
{ {
// Note: AddParameter() is used to ensure existing parameters are not overriden. // Note: AddParameter() is used to ensure existing parameters are not overriden.
context.Response.AddParameter(parameter.Key, parameter.Value switch context.Transaction.Response.AddParameter(parameter.Key, parameter.Value switch
{ {
OpenIddictParameter value => value, OpenIddictParameter value => value,
JsonElement value => value, JsonElement value => value,
@ -425,14 +397,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -449,7 +415,7 @@ namespace OpenIddict.Server.AspNetCore
if (HttpMethods.IsGet(request.Method)) if (HttpMethods.IsGet(request.Method))
{ {
context.Request = new OpenIddictRequest(request.Query); context.Transaction.Request = new OpenIddictRequest(request.Query);
} }
else else
@ -484,14 +450,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -508,7 +468,7 @@ namespace OpenIddict.Server.AspNetCore
if (HttpMethods.IsGet(request.Method)) if (HttpMethods.IsGet(request.Method))
{ {
context.Request = new OpenIddictRequest(request.Query); context.Transaction.Request = new OpenIddictRequest(request.Query);
} }
else if (HttpMethods.IsPost(request.Method)) else if (HttpMethods.IsPost(request.Method))
@ -537,7 +497,7 @@ namespace OpenIddict.Server.AspNetCore
return; return;
} }
context.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted)); context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted));
} }
else else
@ -570,14 +530,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -618,7 +572,7 @@ namespace OpenIddict.Server.AspNetCore
return; return;
} }
context.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted)); context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted));
} }
else else
@ -652,20 +606,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetHttpRequest(); var request = context.Transaction.GetHttpRequest();
@ -682,7 +632,8 @@ namespace OpenIddict.Server.AspNetCore
// At this point, reject requests that use multiple client authentication methods. // At this point, reject requests that use multiple client authentication methods.
// See https://tools.ietf.org/html/rfc6749#section-2.3 for more information. // See https://tools.ietf.org/html/rfc6749#section-2.3 for more information.
if (!string.IsNullOrEmpty(context.Request.ClientAssertion) || !string.IsNullOrEmpty(context.Request.ClientSecret)) if (!string.IsNullOrEmpty(context.Transaction.Request.ClientAssertion) ||
!string.IsNullOrEmpty(context.Transaction.Request.ClientSecret))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7140)); context.Logger.LogError(SR.GetResourceString(SR.ID7140));
@ -709,8 +660,8 @@ namespace OpenIddict.Server.AspNetCore
} }
// Attach the basic authentication credentials to the request message. // Attach the basic authentication credentials to the request message.
context.Request.ClientId = UnescapeDataString(data.Substring(0, index)); context.Transaction.Request.ClientId = UnescapeDataString(data.Substring(0, index));
context.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1)); context.Transaction.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1));
return default; return default;
} }
@ -724,7 +675,7 @@ namespace OpenIddict.Server.AspNetCore
return default; return default;
} }
static string UnescapeDataString(string data) static string? UnescapeDataString(string data)
{ {
if (string.IsNullOrEmpty(data)) if (string.IsNullOrEmpty(data))
{ {
@ -754,14 +705,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -776,6 +721,8 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
string header = request.Headers[HeaderNames.Authorization]; string header = request.Headers[HeaderNames.Authorization];
if (string.IsNullOrEmpty(header) || !header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) if (string.IsNullOrEmpty(header) || !header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
{ {
@ -783,7 +730,7 @@ namespace OpenIddict.Server.AspNetCore
} }
// Attach the access token to the request message. // Attach the access token to the request message.
context.Request.AccessToken = header.Substring("Bearer ".Length); context.Transaction.Request.AccessToken = header.Substring("Bearer ".Length);
return default; return default;
} }
@ -809,14 +756,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -846,14 +787,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -868,6 +803,8 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// When client authentication is made using basic authentication, the authorization server MUST return // When client authentication is made using basic authentication, the authorization server MUST return
// a 401 response with a valid WWW-Authenticate header containing the Basic scheme and a non-empty realm. // a 401 response with a valid WWW-Authenticate header containing the Basic scheme and a non-empty realm.
// A similar error MAY be returned even when basic authentication is not used and MUST also be returned // A similar error MAY be returned even when basic authentication is not used and MUST also be returned
@ -875,7 +812,7 @@ namespace OpenIddict.Server.AspNetCore
// To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors // To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors
// and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials // and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials
// were specified in the request form instead of the HTTP headers, as allowed by the specification. // were specified in the request form instead of the HTTP headers, as allowed by the specification.
response.StatusCode = context.Response.Error switch response.StatusCode = context.Transaction.Response.Error switch
{ {
null => 200, // Note: the default code may be replaced by another handler (e.g when doing redirects). null => 200, // Note: the default code may be replaced by another handler (e.g when doing redirects).
@ -910,14 +847,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -949,7 +880,7 @@ namespace OpenIddict.Server.AspNetCore
{ {
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options; private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public AttachWwwAuthenticateHeader([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options) public AttachWwwAuthenticateHeader(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -963,14 +894,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -985,6 +910,8 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// When client authentication is made using basic authentication, the authorization server MUST return // When client authentication is made using basic authentication, the authorization server MUST return
// a 401 response with a valid WWW-Authenticate header containing the HTTP Basic authentication scheme. // a 401 response with a valid WWW-Authenticate header containing the HTTP Basic authentication scheme.
// A similar error MAY be returned even when basic authentication is not used and MUST also be returned // A similar error MAY be returned even when basic authentication is not used and MUST also be returned
@ -992,7 +919,7 @@ namespace OpenIddict.Server.AspNetCore
// To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors // To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors
// and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials // and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials
// were specified in the request form instead of the HTTP headers, as allowed by the specification. // were specified in the request form instead of the HTTP headers, as allowed by the specification.
var scheme = context.Response.Error switch var scheme = context.Transaction.Response.Error switch
{ {
Errors.InvalidClient => Schemes.Basic, Errors.InvalidClient => Schemes.Basic,
@ -1017,11 +944,11 @@ namespace OpenIddict.Server.AspNetCore
parameters[Parameters.Realm] = _options.CurrentValue.Realm; 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 // 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. // 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.Error, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) || string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal))) string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal)))
@ -1030,7 +957,7 @@ namespace OpenIddict.Server.AspNetCore
} }
// Ignore values that can't be represented as unique strings. // Ignore values that can't be represented as unique strings.
var value = (string) parameter.Value; var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
continue; continue;
@ -1081,14 +1008,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1109,7 +1030,7 @@ namespace OpenIddict.Server.AspNetCore
return default; return default;
} }
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Response); context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Transaction.Response);
context.HandleRequest(); context.HandleRequest();
return default; return default;
@ -1133,14 +1054,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1155,10 +1070,10 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); 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(); 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, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false WriteIndented = false
@ -1196,14 +1111,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1218,7 +1127,9 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
if (string.IsNullOrEmpty(context.Response.Error)) Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{ {
return default; return default;
} }
@ -1248,14 +1159,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1270,7 +1175,9 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
if (string.IsNullOrEmpty(context.Response.Error)) Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{ {
return default; return default;
} }
@ -1311,14 +1218,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1333,24 +1234,26 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
if (string.IsNullOrEmpty(context.Response.Error)) Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{ {
return; return;
} }
// Don't return the state originally sent by the client application. // Don't return the state originally sent by the client application.
context.Response.State = null; context.Transaction.Response.State = null;
context.Logger.LogInformation(SR.GetResourceString(SR.ID7143), context.Response); context.Logger.LogInformation(SR.GetResourceString(SR.ID7143), context.Transaction.Response);
using var stream = new MemoryStream(); using var stream = new MemoryStream();
using var writer = new StreamWriter(stream); using var writer = new StreamWriter(stream);
foreach (var parameter in context.Response.GetParameters()) foreach (var parameter in context.Transaction.Response.GetParameters())
{ {
// Ignore null or empty parameters, including JSON // Ignore null or empty parameters, including JSON
// objects that can't be represented as strings. // objects that can't be represented as strings.
var value = (string) parameter.Value; var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
continue; continue;
@ -1392,14 +1295,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1414,7 +1311,7 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
} }
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName); var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri))
{ {
response.Redirect(properties.RedirectUri); response.Redirect(properties.RedirectUri);
@ -1445,14 +1342,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {

13
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHelpers.cs

@ -5,7 +5,6 @@
*/ */
using System; using System;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using OpenIddict.Server; using OpenIddict.Server;
@ -24,19 +23,19 @@ namespace Microsoft.AspNetCore
/// </summary> /// </summary>
/// <param name="transaction">The transaction instance.</param> /// <param name="transaction">The transaction instance.</param>
/// <returns>The <see cref="HttpRequest"/> instance or <c>null</c> if it couldn't be found.</returns> /// <returns>The <see cref="HttpRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static HttpRequest GetHttpRequest([NotNull] this OpenIddictServerTransaction transaction) public static HttpRequest? GetHttpRequest(this OpenIddictServerTransaction transaction)
{ {
if (transaction == null) if (transaction == null)
{ {
throw new ArgumentNullException(nameof(transaction)); 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; 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; return request;
} }
@ -49,7 +48,7 @@ namespace Microsoft.AspNetCore
/// </summary> /// </summary>
/// <param name="context">The context instance.</param> /// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictServerEndpointType"/>.</returns> /// <returns>The <see cref="OpenIddictServerEndpointType"/>.</returns>
public static OpenIddictServerEndpointType GetOpenIddictServerEndpointType([NotNull] this HttpContext context) public static OpenIddictServerEndpointType GetOpenIddictServerEndpointType(this HttpContext context)
{ {
if (context == null) if (context == null)
{ {
@ -64,7 +63,7 @@ namespace Microsoft.AspNetCore
/// </summary> /// </summary>
/// <param name="context">The context instance.</param> /// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictRequest"/> instance or <c>null</c> if it couldn't be found.</returns> /// <returns>The <see cref="OpenIddictRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictRequest GetOpenIddictServerRequest([NotNull] this HttpContext context) public static OpenIddictRequest? GetOpenIddictServerRequest(this HttpContext context)
{ {
if (context == null) if (context == null)
{ {
@ -79,7 +78,7 @@ namespace Microsoft.AspNetCore
/// </summary> /// </summary>
/// <param name="context">The context instance.</param> /// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictResponse"/> instance or <c>null</c> if it couldn't be found.</returns> /// <returns>The <see cref="OpenIddictResponse"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictResponse GetOpenIddictServerResponse([NotNull] this HttpContext context) public static OpenIddictResponse? GetOpenIddictServerResponse(this HttpContext context)
{ {
if (context == null) if (context == null)
{ {

5
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreOptions.cs

@ -97,10 +97,9 @@ namespace OpenIddict.Server.AspNetCore
public bool EnableStatusCodePagesIntegration { get; set; } public bool EnableStatusCodePagesIntegration { get; set; }
/// <summary> /// <summary>
/// Gets or sets the optional "realm" value returned to /// Gets or sets the optional "realm" value returned to the caller as part of the WWW-Authenticate header.
/// the caller as part of the WWW-Authenticate header.
/// </summary> /// </summary>
public string Realm { get; set; } public string? Realm { get; set; }
/// <summary> /// <summary>
/// Gets or sets the caching policy used by the authorization endpoint. /// Gets or sets the caching policy used by the authorization endpoint.

5
src/OpenIddict.Server.DataProtection/IOpenIddictServerDataProtectionFormatter.cs

@ -6,13 +6,12 @@
using System.IO; using System.IO;
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations;
namespace OpenIddict.Server.DataProtection namespace OpenIddict.Server.DataProtection
{ {
public interface IOpenIddictServerDataProtectionFormatter public interface IOpenIddictServerDataProtectionFormatter
{ {
ClaimsPrincipal ReadToken([NotNull] BinaryReader reader); ClaimsPrincipal? ReadToken(BinaryReader reader);
void WriteToken([NotNull] BinaryWriter writer, [NotNull] ClaimsPrincipal principal); void WriteToken(BinaryWriter writer, ClaimsPrincipal principal);
} }
} }

5
src/OpenIddict.Server.DataProtection/OpenIddict.Server.DataProtection.csproj

@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks> <TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@ -14,12 +15,12 @@
</ItemGroup> </ItemGroup>
<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" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
<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" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection" />
</ItemGroup> </ItemGroup>

13
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionBuilder.cs

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

7
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionConfiguration.cs

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

6
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionExtensions.cs

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

13
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs

@ -12,7 +12,6 @@ using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using JetBrains.Annotations;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
using Properties = OpenIddict.Server.DataProtection.OpenIddictServerDataProtectionConstants.Properties; using Properties = OpenIddict.Server.DataProtection.OpenIddictServerDataProtectionConstants.Properties;
@ -21,7 +20,7 @@ namespace OpenIddict.Server.DataProtection
{ {
public class OpenIddictServerDataProtectionFormatter : IOpenIddictServerDataProtectionFormatter public class OpenIddictServerDataProtectionFormatter : IOpenIddictServerDataProtectionFormatter
{ {
public ClaimsPrincipal ReadToken([NotNull] BinaryReader reader) public ClaimsPrincipal? ReadToken(BinaryReader reader)
{ {
if (reader == null) if (reader == null)
{ {
@ -60,7 +59,7 @@ namespace OpenIddict.Server.DataProtection
.SetClaim(Claims.Private.TokenId, GetProperty(properties, Properties.InternalTokenId)) .SetClaim(Claims.Private.TokenId, GetProperty(properties, Properties.InternalTokenId))
.SetClaim(Claims.Private.UserCodeLifetime, GetProperty(properties, Properties.UserCodeLifetime)); .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. // Read the version of the format used to serialize the ticket.
var version = reader.ReadInt32(); var version = reader.ReadInt32();
@ -177,7 +176,7 @@ namespace OpenIddict.Server.DataProtection
return value; 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; => properties.TryGetValue(name, out var value) ? value : null;
static ImmutableArray<string> GetArrayProperty(IReadOnlyDictionary<string, string> properties, string name) static ImmutableArray<string> GetArrayProperty(IReadOnlyDictionary<string, string> properties, string name)
@ -185,7 +184,7 @@ namespace OpenIddict.Server.DataProtection
JsonSerializer.Deserialize<ImmutableArray<string>>(value) : ImmutableArray.Create<string>(); JsonSerializer.Deserialize<ImmutableArray<string>>(value) : ImmutableArray.Create<string>();
} }
public void WriteToken([NotNull] BinaryWriter writer, [NotNull] ClaimsPrincipal principal) public void WriteToken(BinaryWriter writer, ClaimsPrincipal principal)
{ {
if (writer == null) if (writer == null)
{ {
@ -261,7 +260,7 @@ namespace OpenIddict.Server.DataProtection
// authentication stack and MUST NOT be modified to ensure tokens encrypted using // authentication stack and MUST NOT be modified to ensure tokens encrypted using
// the OpenID Connect server middleware can be read by OpenIddict (and vice-versa). // the OpenID Connect server middleware can be read by OpenIddict (and vice-versa).
static void Write(BinaryWriter writer, string scheme, ClaimsPrincipal principal, IReadOnlyDictionary<string, string> properties) static void Write(BinaryWriter writer, string? scheme, ClaimsPrincipal principal, IReadOnlyDictionary<string, string> properties)
{ {
// Write the version of the format used to serialize the ticket. // Write the version of the format used to serialize the ticket.
writer.Write(/* version: */ 5); writer.Write(/* version: */ 5);
@ -360,7 +359,7 @@ namespace OpenIddict.Server.DataProtection
static void WriteWithDefault(BinaryWriter writer, string value, string defaultValue) static void WriteWithDefault(BinaryWriter writer, string value, string defaultValue)
=> writer.Write(string.Equals(value, defaultValue, StringComparison.Ordinal) ? "\0" : value); => writer.Write(string.Equals(value, defaultValue, StringComparison.Ordinal) ? "\0" : value);
static void SetProperty(IDictionary<string, string> properties, string name, string value) static void SetProperty(IDictionary<string, string> properties, string name, string? value)
{ {
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {

21
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlerFilters.cs

@ -7,7 +7,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.OpenIddictServerEvents;
@ -27,10 +26,10 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public RequireDataProtectionAccessTokenFormatEnabled([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public RequireDataProtectionAccessTokenFormatEnabled(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -49,10 +48,10 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public RequireDataProtectionAuthorizationCodeFormatEnabled([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public RequireDataProtectionAuthorizationCodeFormatEnabled(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -71,10 +70,10 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public RequireDataProtectionDeviceCodeFormatEnabled([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public RequireDataProtectionDeviceCodeFormatEnabled(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -93,10 +92,10 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public RequireDataProtectionRefreshTokenFormatEnabled([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public RequireDataProtectionRefreshTokenFormatEnabled(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -115,10 +114,10 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public RequireDataProtectionUserCodeFormatEnabled([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public RequireDataProtectionUserCodeFormatEnabled(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {

100
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs

@ -10,7 +10,6 @@ using System.ComponentModel;
using System.IO; using System.IO;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -53,7 +52,7 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public ValidateDataProtectionToken([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public ValidateDataProtectionToken(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -66,14 +65,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessAuthenticationContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -120,7 +113,7 @@ namespace OpenIddict.Server.DataProtection
return default; return default;
ClaimsPrincipal ValidateToken(string token, string type) ClaimsPrincipal? ValidateToken(string token, string type)
{ {
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = _options.CurrentValue.DataProtectionProvider.CreateProtector(type switch var protector = _options.CurrentValue.DataProtectionProvider.CreateProtector(type switch
@ -176,7 +169,7 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionAccessToken([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public GenerateDataProtectionAccessToken(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -191,14 +184,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessSignInContext context)
/// </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] ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -211,6 +198,11 @@ namespace OpenIddict.Server.DataProtection
return default; return default;
} }
if (context.AccessTokenPrincipal == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1021));
}
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = context.Options.UseReferenceAccessTokens ? var protector = context.Options.UseReferenceAccessTokens ?
_options.CurrentValue.DataProtectionProvider.CreateProtector( _options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -240,7 +232,7 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionAuthorizationCode([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public GenerateDataProtectionAuthorizationCode(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -255,14 +247,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessSignInContext context)
/// </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] ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -275,6 +261,11 @@ namespace OpenIddict.Server.DataProtection
return default; return default;
} }
if (context.AuthorizationCodePrincipal == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1021));
}
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = !context.Options.DisableTokenStorage ? var protector = !context.Options.DisableTokenStorage ?
_options.CurrentValue.DataProtectionProvider.CreateProtector( _options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -304,7 +295,7 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionDeviceCode([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public GenerateDataProtectionDeviceCode(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -319,14 +310,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessSignInContext context)
/// </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] ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -339,6 +324,11 @@ namespace OpenIddict.Server.DataProtection
return default; return default;
} }
if (context.DeviceCodePrincipal == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1021));
}
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = !context.Options.DisableTokenStorage ? var protector = !context.Options.DisableTokenStorage ?
_options.CurrentValue.DataProtectionProvider.CreateProtector( _options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -368,7 +358,7 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionRefreshToken([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public GenerateDataProtectionRefreshToken(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -383,14 +373,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessSignInContext context)
/// </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] ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -403,6 +387,11 @@ namespace OpenIddict.Server.DataProtection
return default; return default;
} }
if (context.RefreshTokenPrincipal == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1021));
}
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = context.Options.UseReferenceRefreshTokens ? var protector = context.Options.UseReferenceRefreshTokens ?
_options.CurrentValue.DataProtectionProvider.CreateProtector( _options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -432,7 +421,7 @@ namespace OpenIddict.Server.DataProtection
{ {
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options; private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionUserCode([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options) public GenerateDataProtectionUserCode(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -447,14 +436,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessSignInContext context)
/// </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] ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -467,6 +450,11 @@ namespace OpenIddict.Server.DataProtection
return default; return default;
} }
if (context.UserCodePrincipal == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1021));
}
// Create a Data Protection protector using the provider registered in the options. // Create a Data Protection protector using the provider registered in the options.
var protector = !context.Options.DisableTokenStorage ? var protector = !context.Options.DisableTokenStorage ?
_options.CurrentValue.DataProtectionProvider.CreateProtector( _options.CurrentValue.DataProtectionProvider.CreateProtector(

2
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionOptions.cs

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

1
src/OpenIddict.Server.Owin/OpenIddict.Server.Owin.csproj

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

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

@ -6,7 +6,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Owin; using Microsoft.Owin;
using OpenIddict.Server.Owin; using OpenIddict.Server.Owin;
@ -25,7 +24,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictServerOwinBuilder"/>. /// Initializes a new instance of <see cref="OpenIddictServerOwinBuilder"/>.
/// </summary> /// </summary>
/// <param name="services">The services collection.</param> /// <param name="services">The services collection.</param>
public OpenIddictServerOwinBuilder([NotNull] IServiceCollection services) public OpenIddictServerOwinBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services)); => Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary> /// <summary>
@ -40,7 +39,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param> /// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks> /// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder Configure([NotNull] Action<OpenIddictServerOwinOptions> configuration) public OpenIddictServerOwinBuilder Configure(Action<OpenIddictServerOwinOptions> configuration)
{ {
if (configuration == null) if (configuration == null)
{ {
@ -144,7 +143,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="realm">The issuer address.</param> /// <param name="realm">The issuer address.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder SetRealm([NotNull] string realm) public OpenIddictServerOwinBuilder SetRealm(string realm)
{ {
if (string.IsNullOrEmpty(realm)) if (string.IsNullOrEmpty(realm))
{ {
@ -160,7 +159,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="policy">The caching policy.</param> /// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder SetAuthorizationEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy) public OpenIddictServerOwinBuilder SetAuthorizationEndpointCachingPolicy(DistributedCacheEntryOptions policy)
{ {
if (policy == null) if (policy == null)
{ {
@ -176,7 +175,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="policy">The caching policy.</param> /// <param name="policy">The caching policy.</param>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public OpenIddictServerOwinBuilder SetLogoutEndpointCachingPolicy([NotNull] DistributedCacheEntryOptions policy) public OpenIddictServerOwinBuilder SetLogoutEndpointCachingPolicy(DistributedCacheEntryOptions policy)
{ {
if (policy == null) if (policy == null)
{ {
@ -192,7 +191,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param> /// <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> /// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj); public override bool Equals(object? obj) => base.Equals(obj);
/// <summary> /// <summary>
/// Serves as the default hash function. /// Serves as the default hash function.
@ -206,6 +205,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <returns>A string that represents the current object.</returns> /// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString(); public override string? ToString() => base.ToString();
} }
} }

5
src/OpenIddict.Server.Owin/OpenIddictServerOwinConfiguration.cs

@ -5,7 +5,6 @@
*/ */
using System; using System;
using JetBrains.Annotations;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Owin.Security; using Microsoft.Owin.Security;
using SR = OpenIddict.Abstractions.OpenIddictResources; using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -18,7 +17,7 @@ namespace OpenIddict.Server.Owin
public class OpenIddictServerOwinConfiguration : IConfigureOptions<OpenIddictServerOptions>, public class OpenIddictServerOwinConfiguration : IConfigureOptions<OpenIddictServerOptions>,
IPostConfigureOptions<OpenIddictServerOwinOptions> IPostConfigureOptions<OpenIddictServerOwinOptions>
{ {
public void Configure([NotNull] OpenIddictServerOptions options) public void Configure(OpenIddictServerOptions options)
{ {
if (options == null) if (options == null)
{ {
@ -29,7 +28,7 @@ namespace OpenIddict.Server.Owin
options.Handlers.AddRange(OpenIddictServerOwinHandlers.DefaultHandlers); options.Handlers.AddRange(OpenIddictServerOwinHandlers.DefaultHandlers);
} }
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictServerOwinOptions options) public void PostConfigure(string name, OpenIddictServerOwinOptions options)
{ {
if (options == null) if (options == null)
{ {

6
src/OpenIddict.Server.Owin/OpenIddictServerOwinExtensions.cs

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

38
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs

@ -6,9 +6,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Owin; using Microsoft.Owin;
using Microsoft.Owin.Security; using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure; using Microsoft.Owin.Security.Infrastructure;
@ -33,13 +33,14 @@ namespace OpenIddict.Server.Owin
/// <param name="dispatcher">The OpenIddict server dispatcher used by this instance.</param> /// <param name="dispatcher">The OpenIddict server dispatcher used by this instance.</param>
/// <param name="factory">The OpenIddict server factory used by this instance.</param> /// <param name="factory">The OpenIddict server factory used by this instance.</param>
public OpenIddictServerOwinHandler( public OpenIddictServerOwinHandler(
[NotNull] IOpenIddictServerDispatcher dispatcher, IOpenIddictServerDispatcher dispatcher,
[NotNull] IOpenIddictServerFactory factory) IOpenIddictServerFactory factory)
{ {
_dispatcher = dispatcher; _dispatcher = dispatcher;
_factory = factory; _factory = factory;
} }
/// <inheritdoc/>
protected override async Task InitializeCoreAsync() protected override async Task InitializeCoreAsync()
{ {
// Note: the transaction may be already attached when replaying an OWIN request // Note: the transaction may be already attached when replaying an OWIN request
@ -49,7 +50,7 @@ namespace OpenIddict.Server.Owin
{ {
// Create a new transaction and attach the OWIN request to make it available to the OWIN handlers. // Create a new transaction and attach the OWIN request to make it available to the OWIN handlers.
transaction = await _factory.CreateTransactionAsync(); 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 server transaction to the OWIN shared dictionary // Attach the OpenIddict server transaction to the OWIN shared dictionary
// so that it can retrieved while performing sign-in/sign-out operations. // so that it can retrieved while performing sign-in/sign-out operations.
@ -60,9 +61,10 @@ namespace OpenIddict.Server.Owin
await _dispatcher.DispatchAsync(context); await _dispatcher.DispatchAsync(context);
// Store the context in the transaction so that it can be retrieved from InvokeAsync(). // 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() public override async Task<bool> InvokeAsync()
{ {
// Note: due to internal differences between ASP.NET Core and Katana, the request MUST start being processed // Note: due to internal differences between ASP.NET Core and Katana, the request MUST start being processed
@ -72,7 +74,7 @@ namespace OpenIddict.Server.Owin
var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ?? var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
var context = transaction.GetProperty<ProcessRequestContext>(typeof(ProcessRequestContext).FullName) ?? var context = transaction.GetProperty<ProcessRequestContext>(typeof(ProcessRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
if (context.IsRequestHandled) if (context.IsRequestHandled)
@ -115,7 +117,8 @@ namespace OpenIddict.Server.Owin
return false; return false;
} }
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync() /// <inheritdoc/>
protected override async Task<AuthenticationTicket?> AuthenticateCoreAsync()
{ {
var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName); var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName);
if (transaction == null) if (transaction == null)
@ -126,7 +129,7 @@ namespace OpenIddict.Server.Owin
// Note: in many cases, the authentication token was already validated by the time this action is called // 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, // (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. // 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) if (context == null)
{ {
context = new ProcessAuthenticationContext(transaction); context = new ProcessAuthenticationContext(transaction);
@ -134,7 +137,7 @@ namespace OpenIddict.Server.Owin
// Store the context object in the transaction so it can be later retrieved by handlers // 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. // 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) if (context.IsRequestHandled || context.IsRequestSkipped)
@ -152,7 +155,7 @@ namespace OpenIddict.Server.Owin
return null; return null;
} }
var properties = new AuthenticationProperties(new Dictionary<string, string> var properties = new AuthenticationProperties(new Dictionary<string, string?>
{ {
[OpenIddictServerOwinConstants.Properties.Error] = context.Error, [OpenIddictServerOwinConstants.Properties.Error] = context.Error,
[OpenIddictServerOwinConstants.Properties.ErrorDescription] = context.ErrorDescription, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = context.ErrorDescription,
@ -164,17 +167,22 @@ namespace OpenIddict.Server.Owin
else 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) // 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). // 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); return new AuthenticationTicket((ClaimsIdentity) context.Principal.Identity, properties);
} }
} }
/// <inheritdoc/>
protected override async Task TeardownCoreAsync() protected override async Task TeardownCoreAsync()
{ {
// Note: OWIN authentication handlers cannot reliabily write to the response stream // Note: OWIN authentication handlers cannot reliabily write to the response stream
@ -198,7 +206,7 @@ namespace OpenIddict.Server.Owin
var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ?? var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
transaction.Properties[typeof(AuthenticationProperties).FullName] = challenge.Properties ?? new AuthenticationProperties(); transaction.Properties[typeof(AuthenticationProperties).FullName!] = challenge.Properties ?? new AuthenticationProperties();
var context = new ProcessChallengeContext(transaction) var context = new ProcessChallengeContext(transaction)
{ {
@ -241,7 +249,7 @@ namespace OpenIddict.Server.Owin
var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ?? var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
transaction.Properties[typeof(AuthenticationProperties).FullName] = signin.Properties ?? new AuthenticationProperties(); transaction.Properties[typeof(AuthenticationProperties).FullName!] = signin.Properties ?? new AuthenticationProperties();
var context = new ProcessSignInContext(transaction) var context = new ProcessSignInContext(transaction)
{ {
@ -285,7 +293,7 @@ namespace OpenIddict.Server.Owin
var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ?? var transaction = Context.Get<OpenIddictServerTransaction>(typeof(OpenIddictServerTransaction).FullName) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
transaction.Properties[typeof(AuthenticationProperties).FullName] = signout.Properties ?? new AuthenticationProperties(); transaction.Properties[typeof(AuthenticationProperties).FullName!] = signout.Properties ?? new AuthenticationProperties();
var context = new ProcessSignOutContext(transaction) var context = new ProcessSignOutContext(transaction)
{ {

39
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlerFilters.cs

@ -6,7 +6,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Owin; using Owin;
using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.OpenIddictServerEvents;
@ -25,10 +24,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireAuthorizationEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireAuthorizationEndpointCachingEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -47,10 +46,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireAuthorizationEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireAuthorizationEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -68,10 +67,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireErrorPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireErrorPassthroughEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -89,10 +88,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireLogoutEndpointCachingEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireLogoutEndpointCachingEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -111,10 +110,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireLogoutEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireLogoutEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -130,7 +129,7 @@ namespace OpenIddict.Server.Owin
/// </summary> /// </summary>
public class RequireOwinRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireOwinRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -148,10 +147,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireTransportSecurityRequirementEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireTransportSecurityRequirementEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -170,10 +169,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireTokenEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireTokenEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -192,10 +191,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireUserinfoEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireUserinfoEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -214,10 +213,10 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public RequireVerificationEndpointPassthroughEnabled([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public RequireVerificationEndpointPassthroughEnabled(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {

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

@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
@ -15,7 +16,6 @@ using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -71,7 +71,7 @@ namespace OpenIddict.Server.Owin
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache) public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -86,20 +86,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
/// </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] ExtractAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// If a request_id parameter can be found in the authorization request, // If a request_id parameter can be found in the authorization request,
// restore the complete authorization request from the distributed cache. // restore the complete authorization request from the distributed cache.
@ -172,8 +168,8 @@ namespace OpenIddict.Server.Owin
public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public CacheRequestParameters( public CacheRequestParameters(
[NotNull] IDistributedCache cache, IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) IOptionsMonitor<OpenIddictServerOwinOptions> options)
{ {
_cache = cache; _cache = cache;
_options = options; _options = options;
@ -191,20 +187,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
/// </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] ExtractAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest(); var request = context.Transaction.GetOwinRequest();
@ -279,7 +271,7 @@ namespace OpenIddict.Server.Owin
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache) public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -294,14 +286,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -331,7 +317,7 @@ namespace OpenIddict.Server.Owin
{ {
private readonly HtmlEncoder _encoder; private readonly HtmlEncoder _encoder;
public ProcessFormPostResponse([NotNull] HtmlEncoder encoder) public ProcessFormPostResponse(HtmlEncoder encoder)
=> _encoder = encoder; => _encoder = encoder;
/// <summary> /// <summary>
@ -345,14 +331,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -393,9 +373,10 @@ namespace OpenIddict.Server.Owin
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
writer.WriteLine($@"<input type=""hidden"" name=""{_encoder.Encode(key)}"" value=""{_encoder.Encode(value)}"" />"); writer.WriteLine($@"<input type=""hidden"" name=""{_encoder.Encode(key)}"" value=""{_encoder.Encode(value)}"" />");
@ -441,14 +422,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -478,9 +453,10 @@ namespace OpenIddict.Server.Owin
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
location = WebUtilities.AddQueryString(location, key, value); location = WebUtilities.AddQueryString(location, key, value);
@ -510,14 +486,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -547,9 +517,10 @@ namespace OpenIddict.Server.Owin
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
builder.Append(Contains(builder, '#') ? '&' : '#') builder.Append(Contains(builder, '#') ? '&' : '#')

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

@ -7,12 +7,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -68,7 +68,7 @@ namespace OpenIddict.Server.Owin
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache) public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -83,20 +83,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
/// </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] ExtractLogoutRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// If a request_id parameter can be found in the logout request, // If a request_id parameter can be found in the logout request,
// restore the complete logout request from the distributed cache. // restore the complete logout request from the distributed cache.
@ -169,8 +165,8 @@ namespace OpenIddict.Server.Owin
public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public CacheRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public CacheRequestParameters( public CacheRequestParameters(
[NotNull] IDistributedCache cache, IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) IOptionsMonitor<OpenIddictServerOwinOptions> options)
{ {
_cache = cache; _cache = cache;
_options = options; _options = options;
@ -188,20 +184,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
/// </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] ExtractLogoutRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest(); var request = context.Transaction.GetOwinRequest();
@ -276,7 +268,7 @@ namespace OpenIddict.Server.Owin
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115)); public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache) public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache; => _cache = cache;
/// <summary> /// <summary>
@ -291,14 +283,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyLogoutResponseContext context)
/// </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] ApplyLogoutResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -337,14 +323,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyLogoutResponseContext context)
/// </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] ApplyLogoutResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -373,9 +353,10 @@ namespace OpenIddict.Server.Owin
// For consistency, multiple parameters with the same name are also supported by this endpoint. // For consistency, multiple parameters with the same name are also supported by this endpoint.
foreach (var (key, value) in foreach (var (key, value) in
from parameter in context.Response.GetParameters() from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value let values = (string?[]?) parameter.Value
where values != null where values != null
from value in values from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value)) select (parameter.Key, Value: value))
{ {
location = WebUtilities.AddQueryString(location, key, value); location = WebUtilities.AddQueryString(location, key, value);

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

@ -8,12 +8,12 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Owin; using Microsoft.Owin;
@ -72,14 +72,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessRequestContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -180,14 +174,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessRequestContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -218,7 +206,7 @@ namespace OpenIddict.Server.Owin
return default; 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()) !issuer.IsWellFormedOriginalString())
{ {
context.Reject( context.Reject(
@ -252,14 +240,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessRequestContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -311,21 +293,15 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ProcessChallengeContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); 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) if (properties != null)
{ {
context.Response.Error = GetProperty(properties, Properties.Error); context.Response.Error = GetProperty(properties, Properties.Error);
@ -336,8 +312,8 @@ namespace OpenIddict.Server.Owin
return default; return default;
static string GetProperty(AuthenticationProperties properties, string name) static string? GetProperty(AuthenticationProperties properties, string name)
=> properties.Dictionary.TryGetValue(name, out string value) ? value : null; => properties.Dictionary.TryGetValue(name, out string? value) ? value : null;
} }
} }
@ -358,14 +334,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -382,7 +352,7 @@ namespace OpenIddict.Server.Owin
if (string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase)) if (string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase))
{ {
context.Request = new OpenIddictRequest(request.Query); context.Transaction.Request = new OpenIddictRequest(request.Query);
} }
else else
@ -417,14 +387,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -441,7 +405,7 @@ namespace OpenIddict.Server.Owin
if (string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase)) if (string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase))
{ {
context.Request = new OpenIddictRequest(request.Query); context.Transaction.Request = new OpenIddictRequest(request.Query);
} }
else if (string.Equals(request.Method, "POST", StringComparison.OrdinalIgnoreCase)) else if (string.Equals(request.Method, "POST", StringComparison.OrdinalIgnoreCase))
@ -470,7 +434,7 @@ namespace OpenIddict.Server.Owin
return; return;
} }
context.Request = new OpenIddictRequest(await request.ReadFormAsync()); context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync());
} }
else else
@ -503,14 +467,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -551,7 +509,7 @@ namespace OpenIddict.Server.Owin
return; return;
} }
context.Request = new OpenIddictRequest(await request.ReadFormAsync()); context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync());
} }
else else
@ -585,20 +543,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest(); var request = context.Transaction.GetOwinRequest();
@ -615,7 +569,8 @@ namespace OpenIddict.Server.Owin
// At this point, reject requests that use multiple client authentication methods. // At this point, reject requests that use multiple client authentication methods.
// See https://tools.ietf.org/html/rfc6749#section-2.3 for more information. // See https://tools.ietf.org/html/rfc6749#section-2.3 for more information.
if (!string.IsNullOrEmpty(context.Request.ClientAssertion) || !string.IsNullOrEmpty(context.Request.ClientSecret)) if (!string.IsNullOrEmpty(context.Transaction.Request.ClientAssertion) ||
!string.IsNullOrEmpty(context.Transaction.Request.ClientSecret))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7140)); context.Logger.LogError(SR.GetResourceString(SR.ID7140));
@ -642,8 +597,8 @@ namespace OpenIddict.Server.Owin
} }
// Attach the basic authentication credentials to the request message. // Attach the basic authentication credentials to the request message.
context.Request.ClientId = UnescapeDataString(data.Substring(0, index)); context.Transaction.Request.ClientId = UnescapeDataString(data.Substring(0, index));
context.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1)); context.Transaction.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1));
return default; return default;
} }
@ -657,7 +612,7 @@ namespace OpenIddict.Server.Owin
return default; return default;
} }
static string UnescapeDataString(string data) static string? UnescapeDataString(string data)
{ {
if (string.IsNullOrEmpty(data)) if (string.IsNullOrEmpty(data))
{ {
@ -687,20 +642,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved, // 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. // this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest(); var request = context.Transaction.GetOwinRequest();
@ -716,7 +667,7 @@ namespace OpenIddict.Server.Owin
} }
// Attach the access token to the request message. // Attach the access token to the request message.
context.Request.AccessToken = header.Substring("Bearer ".Length); context.Transaction.Request.AccessToken = header.Substring("Bearer ".Length);
return default; return default;
} }
@ -742,14 +693,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -779,20 +724,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); 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 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. // this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response; var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -808,7 +749,7 @@ namespace OpenIddict.Server.Owin
// To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors // To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors
// and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials // and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials
// were specified in the request form instead of the HTTP headers, as allowed by the specification. // were specified in the request form instead of the HTTP headers, as allowed by the specification.
response.StatusCode = context.Response.Error switch response.StatusCode = context.Transaction.Response.Error switch
{ {
null => 200, // Note: the default code may be replaced by another handler (e.g when doing redirects). null => 200, // Note: the default code may be replaced by another handler (e.g when doing redirects).
@ -843,14 +784,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -882,7 +817,7 @@ namespace OpenIddict.Server.Owin
{ {
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options; private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public AttachWwwAuthenticateHeader([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options) public AttachWwwAuthenticateHeader(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options; => _options = options;
/// <summary> /// <summary>
@ -896,20 +831,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); 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 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. // this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response; var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -925,7 +856,7 @@ namespace OpenIddict.Server.Owin
// To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors // To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors
// and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials // and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials
// were specified in the request form instead of the HTTP headers, as allowed by the specification. // were specified in the request form instead of the HTTP headers, as allowed by the specification.
var scheme = context.Response.Error switch var scheme = context.Transaction.Response.Error switch
{ {
Errors.InvalidClient => Schemes.Basic, Errors.InvalidClient => Schemes.Basic,
@ -950,11 +881,11 @@ namespace OpenIddict.Server.Owin
parameters[Parameters.Realm] = _options.CurrentValue.Realm; 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 // 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. // 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.Error, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) || string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal))) string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal)))
@ -963,7 +894,7 @@ namespace OpenIddict.Server.Owin
} }
// Ignore values that can't be represented as unique strings. // Ignore values that can't be represented as unique strings.
var value = (string) parameter.Value; var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
continue; continue;
@ -1014,14 +945,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1042,7 +967,7 @@ namespace OpenIddict.Server.Owin
return default; return default;
} }
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Response); context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Transaction.Response);
context.HandleRequest(); context.HandleRequest();
return default; return default;
@ -1066,14 +991,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1088,10 +1007,10 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119)); 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(); 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, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false WriteIndented = false
@ -1129,20 +1048,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); 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 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. // this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response; var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -1151,13 +1066,13 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
} }
if (string.IsNullOrEmpty(context.Response.Error)) if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{ {
return default; return default;
} }
// Don't return the state originally sent by the client application. // Don't return the state originally sent by the client application.
context.Response.State = null; context.Transaction.Response.State = null;
context.SkipRequest(); context.SkipRequest();
@ -1183,20 +1098,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); 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 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. // this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response; var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -1205,24 +1116,24 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
} }
if (string.IsNullOrEmpty(context.Response.Error)) if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{ {
return; return;
} }
// Don't return the state originally sent by the client application. // Don't return the state originally sent by the client application.
context.Response.State = null; context.Transaction.Response.State = null;
context.Logger.LogInformation(SR.GetResourceString(SR.ID7143), context.Response); context.Logger.LogInformation(SR.GetResourceString(SR.ID7143), context.Transaction.Response);
using var stream = new MemoryStream(); using var stream = new MemoryStream();
using var writer = new StreamWriter(stream); using var writer = new StreamWriter(stream);
foreach (var parameter in context.Response.GetParameters()) foreach (var parameter in context.Transaction.Response.GetParameters())
{ {
// Ignore null or empty parameters, including JSON // Ignore null or empty parameters, including JSON
// objects that can't be represented as strings. // objects that can't be represented as strings.
var value = (string) parameter.Value; var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
continue; continue;
@ -1264,14 +1175,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1286,7 +1191,7 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
} }
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName); var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri))
{ {
response.Redirect(properties.RedirectUri); response.Redirect(properties.RedirectUri);
@ -1317,14 +1222,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {

15
src/OpenIddict.Server.Owin/OpenIddictServerOwinHelpers.cs

@ -5,7 +5,6 @@
*/ */
using System; using System;
using JetBrains.Annotations;
using Microsoft.Owin; using Microsoft.Owin;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using OpenIddict.Server; using OpenIddict.Server;
@ -26,7 +25,7 @@ namespace Owin
/// </summary> /// </summary>
/// <param name="app">The application builder used to register middleware instances.</param> /// <param name="app">The application builder used to register middleware instances.</param>
/// <returns>The <see cref="IAppBuilder"/>.</returns> /// <returns>The <see cref="IAppBuilder"/>.</returns>
public static IAppBuilder UseOpenIddictServer([NotNull] this IAppBuilder app) public static IAppBuilder UseOpenIddictServer(this IAppBuilder app)
{ {
if (app == null) if (app == null)
{ {
@ -41,19 +40,19 @@ namespace Owin
/// </summary> /// </summary>
/// <param name="transaction">The transaction instance.</param> /// <param name="transaction">The transaction instance.</param>
/// <returns>The <see cref="IOwinRequest"/> instance or <c>null</c> if it couldn't be found.</returns> /// <returns>The <see cref="IOwinRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static IOwinRequest GetOwinRequest([NotNull] this OpenIddictServerTransaction transaction) public static IOwinRequest? GetOwinRequest(this OpenIddictServerTransaction transaction)
{ {
if (transaction == null) if (transaction == null)
{ {
throw new ArgumentNullException(nameof(transaction)); 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; 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; return request;
} }
@ -66,7 +65,7 @@ namespace Owin
/// </summary> /// </summary>
/// <param name="context">The context instance.</param> /// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictServerEndpointType"/>.</returns> /// <returns>The <see cref="OpenIddictServerEndpointType"/>.</returns>
public static OpenIddictServerEndpointType GetOpenIddictServerEndpointType([NotNull] this IOwinContext context) public static OpenIddictServerEndpointType GetOpenIddictServerEndpointType(this IOwinContext context)
{ {
if (context == null) if (context == null)
{ {
@ -81,7 +80,7 @@ namespace Owin
/// </summary> /// </summary>
/// <param name="context">The context instance.</param> /// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictRequest"/> instance or <c>null</c> if it couldn't be found.</returns> /// <returns>The <see cref="OpenIddictRequest"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictRequest GetOpenIddictServerRequest([NotNull] this IOwinContext context) public static OpenIddictRequest? GetOpenIddictServerRequest(this IOwinContext context)
{ {
if (context == null) if (context == null)
{ {
@ -96,7 +95,7 @@ namespace Owin
/// </summary> /// </summary>
/// <param name="context">The context instance.</param> /// <param name="context">The context instance.</param>
/// <returns>The <see cref="OpenIddictResponse"/> instance or <c>null</c> if it couldn't be found.</returns> /// <returns>The <see cref="OpenIddictResponse"/> instance or <c>null</c> if it couldn't be found.</returns>
public static OpenIddictResponse GetOpenIddictServerResponse([NotNull] this IOwinContext context) public static OpenIddictResponse? GetOpenIddictServerResponse(this IOwinContext context)
{ {
if (context == null) if (context == null)
{ {

9
src/OpenIddict.Server.Owin/OpenIddictServerOwinMiddleware.cs

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

5
src/OpenIddict.Server.Owin/OpenIddictServerOwinMiddlewareFactory.cs

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

5
src/OpenIddict.Server.Owin/OpenIddictServerOwinOptions.cs

@ -94,10 +94,9 @@ namespace OpenIddict.Server.Owin
public bool EnableLogoutEndpointCaching { get; set; } public bool EnableLogoutEndpointCaching { get; set; }
/// <summary> /// <summary>
/// Gets or sets the optional "realm" value returned to /// Gets or sets the optional "realm" value returned to the caller as part of the WWW-Authenticate header.
/// the caller as part of the WWW-Authenticate header.
/// </summary> /// </summary>
public string Realm { get; set; } public string? Realm { get; set; }
/// <summary> /// <summary>
/// Gets or sets the caching policy used by the authorization endpoint. /// Gets or sets the caching policy used by the authorization endpoint.

3
src/OpenIddict.Server/IOpenIddictServerDispatcher.cs

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

3
src/OpenIddict.Server/IOpenIddictServerHandler.cs

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

3
src/OpenIddict.Server/IOpenIddictServerHandlerFilter.cs

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

1
src/OpenIddict.Server/OpenIddict.Server.csproj

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

133
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -12,7 +12,6 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using OpenIddict.Server; using OpenIddict.Server;
@ -31,7 +30,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// Initializes a new instance of <see cref="OpenIddictServerBuilder"/>. /// Initializes a new instance of <see cref="OpenIddictServerBuilder"/>.
/// </summary> /// </summary>
/// <param name="services">The services collection.</param> /// <param name="services">The services collection.</param>
public OpenIddictServerBuilder([NotNull] IServiceCollection services) public OpenIddictServerBuilder(IServiceCollection services)
=> Services = services ?? throw new ArgumentNullException(nameof(services)); => Services = services ?? throw new ArgumentNullException(nameof(services));
/// <summary> /// <summary>
@ -48,7 +47,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)] [EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictServerBuilder AddEventHandler<TContext>( public OpenIddictServerBuilder AddEventHandler<TContext>(
[NotNull] Action<OpenIddictServerHandlerDescriptor.Builder<TContext>> configuration) Action<OpenIddictServerHandlerDescriptor.Builder<TContext>> configuration)
where TContext : OpenIddictServerEvents.BaseContext where TContext : OpenIddictServerEvents.BaseContext
{ {
if (configuration == null) if (configuration == null)
@ -71,7 +70,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="descriptor">The handler descriptor.</param> /// <param name="descriptor">The handler descriptor.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)] [EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictServerBuilder AddEventHandler([NotNull] OpenIddictServerHandlerDescriptor descriptor) public OpenIddictServerBuilder AddEventHandler(OpenIddictServerHandlerDescriptor descriptor)
{ {
if (descriptor == null) if (descriptor == null)
{ {
@ -90,7 +89,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="descriptor">The descriptor corresponding to the handler to remove.</param> /// <param name="descriptor">The descriptor corresponding to the handler to remove.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Advanced)] [EditorBrowsable(EditorBrowsableState.Advanced)]
public OpenIddictServerBuilder RemoveEventHandler([NotNull] OpenIddictServerHandlerDescriptor descriptor) public OpenIddictServerBuilder RemoveEventHandler(OpenIddictServerHandlerDescriptor descriptor)
{ {
if (descriptor == null) if (descriptor == null)
{ {
@ -119,7 +118,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The delegate used to configure the OpenIddict options.</param> /// <param name="configuration">The delegate used to configure the OpenIddict options.</param>
/// <remarks>This extension can be safely called multiple times.</remarks> /// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder Configure([NotNull] Action<OpenIddictServerOptions> configuration) public OpenIddictServerBuilder Configure(Action<OpenIddictServerOptions> configuration)
{ {
if (configuration == null) if (configuration == null)
{ {
@ -145,7 +144,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="credentials">The encrypting credentials.</param> /// <param name="credentials">The encrypting credentials.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCredentials([NotNull] EncryptingCredentials credentials) public OpenIddictServerBuilder AddEncryptionCredentials(EncryptingCredentials credentials)
{ {
if (credentials == null) if (credentials == null)
{ {
@ -160,7 +159,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="key">The security key.</param> /// <param name="key">The security key.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionKey([NotNull] SecurityKey key) public OpenIddictServerBuilder AddEncryptionKey(SecurityKey key)
{ {
if (key == null) if (key == null)
{ {
@ -203,7 +202,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The X.509 certificate is attached to the server options.")] Justification = "The X.509 certificate is attached to the server options.")]
public OpenIddictServerBuilder AddDevelopmentEncryptionCertificate([NotNull] X500DistinguishedName subject) public OpenIddictServerBuilder AddDevelopmentEncryptionCertificate(X500DistinguishedName subject)
{ {
if (subject == null) if (subject == null)
{ {
@ -296,7 +295,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="algorithm">The algorithm associated with the encryption key.</param> /// <param name="algorithm">The algorithm associated with the encryption key.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEphemeralEncryptionKey([NotNull] string algorithm) public OpenIddictServerBuilder AddEphemeralEncryptionKey(string algorithm)
{ {
if (string.IsNullOrEmpty(algorithm)) if (string.IsNullOrEmpty(algorithm))
{ {
@ -369,7 +368,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="certificate">The encryption certificate.</param> /// <param name="certificate">The encryption certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCertificate([NotNull] X509Certificate2 certificate) public OpenIddictServerBuilder AddEncryptionCertificate(X509Certificate2 certificate)
{ {
if (certificate == null) if (certificate == null)
{ {
@ -402,8 +401,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="resource">The name of the embedded resource.</param> /// <param name="resource">The name of the embedded resource.</param>
/// <param name="password">The password used to open the certificate.</param> /// <param name="password">The password used to open the certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCertificate( public OpenIddictServerBuilder AddEncryptionCertificate(Assembly assembly, string resource, string password)
[NotNull] Assembly assembly, [NotNull] string resource, [NotNull] string password)
#if SUPPORTS_EPHEMERAL_KEY_SETS #if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS. // Note: ephemeral key sets are currently not supported on macOS.
=> AddEncryptionCertificate(assembly, resource, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? => AddEncryptionCertificate(assembly, resource, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
@ -422,8 +420,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> /// <param name="flags">An enumeration of flags indicating how and where to store the private key of the certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCertificate( public OpenIddictServerBuilder AddEncryptionCertificate(
[NotNull] Assembly assembly, [NotNull] string resource, Assembly assembly, string resource,
[NotNull] string password, X509KeyStorageFlags flags) string password, X509KeyStorageFlags flags)
{ {
if (assembly == null) if (assembly == null)
{ {
@ -455,7 +453,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="stream">The stream containing the certificate.</param> /// <param name="stream">The stream containing the certificate.</param>
/// <param name="password">The password used to open the certificate.</param> /// <param name="password">The password used to open the certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCertificate([NotNull] Stream stream, [NotNull] string password) public OpenIddictServerBuilder AddEncryptionCertificate(Stream stream, string password)
#if SUPPORTS_EPHEMERAL_KEY_SETS #if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS. // Note: ephemeral key sets are currently not supported on macOS.
=> AddEncryptionCertificate(stream, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? => AddEncryptionCertificate(stream, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
@ -477,8 +475,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The X.509 certificate is attached to the server options.")] Justification = "The X.509 certificate is attached to the server options.")]
public OpenIddictServerBuilder AddEncryptionCertificate( public OpenIddictServerBuilder AddEncryptionCertificate(Stream stream, string password, X509KeyStorageFlags flags)
[NotNull] Stream stream, [NotNull] string password, X509KeyStorageFlags flags)
{ {
if (stream == null) if (stream == null)
{ {
@ -501,7 +498,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X.509 store.</param> /// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X.509 store.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCertificate([NotNull] string thumbprint) public OpenIddictServerBuilder AddEncryptionCertificate(string thumbprint)
{ {
if (string.IsNullOrEmpty(thumbprint)) if (string.IsNullOrEmpty(thumbprint))
{ {
@ -516,7 +513,7 @@ namespace Microsoft.Extensions.DependencyInjection
return AddEncryptionCertificate(certificate); return AddEncryptionCertificate(certificate);
static X509Certificate2 GetCertificate(StoreLocation location, string thumbprint) static X509Certificate2? GetCertificate(StoreLocation location, string thumbprint)
{ {
using var store = new X509Store(StoreName.My, location); using var store = new X509Store(StoreName.My, location);
store.Open(OpenFlags.ReadOnly); store.Open(OpenFlags.ReadOnly);
@ -534,8 +531,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="name">The name of the X.509 store.</param> /// <param name="name">The name of the X.509 store.</param>
/// <param name="location">The location of the X.509 store.</param> /// <param name="location">The location of the X.509 store.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddEncryptionCertificate( public OpenIddictServerBuilder AddEncryptionCertificate(string thumbprint, StoreName name, StoreLocation location)
[NotNull] string thumbprint, StoreName name, StoreLocation location)
{ {
if (string.IsNullOrEmpty(thumbprint)) if (string.IsNullOrEmpty(thumbprint))
{ {
@ -562,7 +558,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="credentials">The signing credentials.</param> /// <param name="credentials">The signing credentials.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCredentials([NotNull] SigningCredentials credentials) public OpenIddictServerBuilder AddSigningCredentials(SigningCredentials credentials)
{ {
if (credentials == null) if (credentials == null)
{ {
@ -577,7 +573,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="key">The security key.</param> /// <param name="key">The security key.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningKey([NotNull] SecurityKey key) public OpenIddictServerBuilder AddSigningKey(SecurityKey key)
{ {
if (key == null) if (key == null)
{ {
@ -643,7 +639,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The X.509 certificate is attached to the server options.")] Justification = "The X.509 certificate is attached to the server options.")]
public OpenIddictServerBuilder AddDevelopmentSigningCertificate([NotNull] X500DistinguishedName subject) public OpenIddictServerBuilder AddDevelopmentSigningCertificate(X500DistinguishedName subject)
{ {
if (subject == null) if (subject == null)
{ {
@ -738,7 +734,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The X.509 certificate is attached to the server options.")] Justification = "The X.509 certificate is attached to the server options.")]
public OpenIddictServerBuilder AddEphemeralSigningKey([NotNull] string algorithm) public OpenIddictServerBuilder AddEphemeralSigningKey(string algorithm)
{ {
if (string.IsNullOrEmpty(algorithm)) if (string.IsNullOrEmpty(algorithm))
{ {
@ -828,7 +824,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="certificate">The signing certificate.</param> /// <param name="certificate">The signing certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCertificate([NotNull] X509Certificate2 certificate) public OpenIddictServerBuilder AddSigningCertificate(X509Certificate2 certificate)
{ {
if (certificate == null) if (certificate == null)
{ {
@ -861,8 +857,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="resource">The name of the embedded resource.</param> /// <param name="resource">The name of the embedded resource.</param>
/// <param name="password">The password used to open the certificate.</param> /// <param name="password">The password used to open the certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCertificate( public OpenIddictServerBuilder AddSigningCertificate(Assembly assembly, string resource, string password)
[NotNull] Assembly assembly, [NotNull] string resource, [NotNull] string password)
#if SUPPORTS_EPHEMERAL_KEY_SETS #if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS. // Note: ephemeral key sets are currently not supported on macOS.
=> AddSigningCertificate(assembly, resource, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? => AddSigningCertificate(assembly, resource, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
@ -881,8 +876,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> /// <param name="flags">An enumeration of flags indicating how and where to store the private key of the certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCertificate( public OpenIddictServerBuilder AddSigningCertificate(
[NotNull] Assembly assembly, [NotNull] string resource, Assembly assembly, string resource,
[NotNull] string password, X509KeyStorageFlags flags) string password, X509KeyStorageFlags flags)
{ {
if (assembly == null) if (assembly == null)
{ {
@ -914,7 +909,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="stream">The stream containing the certificate.</param> /// <param name="stream">The stream containing the certificate.</param>
/// <param name="password">The password used to open the certificate.</param> /// <param name="password">The password used to open the certificate.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCertificate([NotNull] Stream stream, [NotNull] string password) public OpenIddictServerBuilder AddSigningCertificate(Stream stream, string password)
#if SUPPORTS_EPHEMERAL_KEY_SETS #if SUPPORTS_EPHEMERAL_KEY_SETS
// Note: ephemeral key sets are currently not supported on macOS. // Note: ephemeral key sets are currently not supported on macOS.
=> AddSigningCertificate(stream, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? => AddSigningCertificate(stream, password, RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ?
@ -936,8 +931,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope",
Justification = "The X.509 certificate is attached to the server options.")] Justification = "The X.509 certificate is attached to the server options.")]
public OpenIddictServerBuilder AddSigningCertificate( public OpenIddictServerBuilder AddSigningCertificate(Stream stream, string password, X509KeyStorageFlags flags)
[NotNull] Stream stream, [NotNull] string password, X509KeyStorageFlags flags)
{ {
if (stream == null) if (stream == null)
{ {
@ -960,7 +954,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X.509 store.</param> /// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X.509 store.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCertificate([NotNull] string thumbprint) public OpenIddictServerBuilder AddSigningCertificate(string thumbprint)
{ {
if (string.IsNullOrEmpty(thumbprint)) if (string.IsNullOrEmpty(thumbprint))
{ {
@ -975,7 +969,7 @@ namespace Microsoft.Extensions.DependencyInjection
return AddSigningCertificate(certificate); return AddSigningCertificate(certificate);
static X509Certificate2 GetCertificate(StoreLocation location, string thumbprint) static X509Certificate2? GetCertificate(StoreLocation location, string thumbprint)
{ {
using var store = new X509Store(StoreName.My, location); using var store = new X509Store(StoreName.My, location);
store.Open(OpenFlags.ReadOnly); store.Open(OpenFlags.ReadOnly);
@ -993,8 +987,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="name">The name of the X.509 store.</param> /// <param name="name">The name of the X.509 store.</param>
/// <param name="location">The location of the X.509 store.</param> /// <param name="location">The location of the X.509 store.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AddSigningCertificate( public OpenIddictServerBuilder AddSigningCertificate(string thumbprint, StoreName name, StoreLocation location)
[NotNull] string thumbprint, StoreName name, StoreLocation location)
{ {
if (string.IsNullOrEmpty(thumbprint)) if (string.IsNullOrEmpty(thumbprint))
{ {
@ -1039,7 +1032,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="type">The grant type associated with the flow.</param> /// <param name="type">The grant type associated with the flow.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder AllowCustomFlow([NotNull] string type) public OpenIddictServerBuilder AllowCustomFlow(string type)
{ {
if (string.IsNullOrEmpty(type)) if (string.IsNullOrEmpty(type))
{ {
@ -1090,7 +1083,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetAuthorizationEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetAuthorizationEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1107,7 +1100,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetAuthorizationEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetAuthorizationEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1133,7 +1126,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetConfigurationEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetConfigurationEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1150,7 +1143,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetConfigurationEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetConfigurationEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1176,7 +1169,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetCryptographyEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetCryptographyEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1193,7 +1186,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetCryptographyEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetCryptographyEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1219,7 +1212,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetDeviceEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetDeviceEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1236,7 +1229,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetDeviceEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetDeviceEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1262,7 +1255,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetIntrospectionEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetIntrospectionEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1279,7 +1272,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetIntrospectionEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetIntrospectionEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1305,7 +1298,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetLogoutEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetLogoutEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1322,7 +1315,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetLogoutEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetLogoutEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1348,7 +1341,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetRevocationEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetRevocationEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1365,7 +1358,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetRevocationEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetRevocationEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1391,7 +1384,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetTokenEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetTokenEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1408,7 +1401,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetTokenEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetTokenEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1434,7 +1427,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetUserinfoEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetUserinfoEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1451,7 +1444,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetUserinfoEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetUserinfoEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1477,7 +1470,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetVerificationEndpointUris([NotNull] params string[] addresses) public OpenIddictServerBuilder SetVerificationEndpointUris(params string[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1494,7 +1487,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="addresses">The addresses associated to the endpoint.</param> /// <param name="addresses">The addresses associated to the endpoint.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetVerificationEndpointUris([NotNull] params Uri[] addresses) public OpenIddictServerBuilder SetVerificationEndpointUris(params Uri[] addresses)
{ {
if (addresses == null) if (addresses == null)
{ {
@ -1601,7 +1594,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="claims">The supported claims.</param> /// <param name="claims">The supported claims.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder RegisterClaims([NotNull] params string[] claims) public OpenIddictServerBuilder RegisterClaims(params string[] claims)
{ {
if (claims == null) if (claims == null)
{ {
@ -1622,7 +1615,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="scopes">The supported scopes.</param> /// <param name="scopes">The supported scopes.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder RegisterScopes([NotNull] params string[] scopes) public OpenIddictServerBuilder RegisterScopes(params string[] scopes)
{ {
if (scopes == null) if (scopes == null)
{ {
@ -1646,7 +1639,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="lifetime">The access token lifetime.</param> /// <param name="lifetime">The access token lifetime.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetAccessTokenLifetime([CanBeNull] TimeSpan? lifetime) public OpenIddictServerBuilder SetAccessTokenLifetime(TimeSpan? lifetime)
=> Configure(options => options.AccessTokenLifetime = lifetime); => Configure(options => options.AccessTokenLifetime = lifetime);
/// <summary> /// <summary>
@ -1657,7 +1650,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="lifetime">The authorization code lifetime.</param> /// <param name="lifetime">The authorization code lifetime.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetAuthorizationCodeLifetime([CanBeNull] TimeSpan? lifetime) public OpenIddictServerBuilder SetAuthorizationCodeLifetime(TimeSpan? lifetime)
=> Configure(options => options.AuthorizationCodeLifetime = lifetime); => Configure(options => options.AuthorizationCodeLifetime = lifetime);
/// <summary> /// <summary>
@ -1668,7 +1661,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="lifetime">The authorization code lifetime.</param> /// <param name="lifetime">The authorization code lifetime.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetDeviceCodeLifetime([CanBeNull] TimeSpan? lifetime) public OpenIddictServerBuilder SetDeviceCodeLifetime(TimeSpan? lifetime)
=> Configure(options => options.DeviceCodeLifetime = lifetime); => Configure(options => options.DeviceCodeLifetime = lifetime);
/// <summary> /// <summary>
@ -1678,7 +1671,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="lifetime">The identity token lifetime.</param> /// <param name="lifetime">The identity token lifetime.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetIdentityTokenLifetime([CanBeNull] TimeSpan? lifetime) public OpenIddictServerBuilder SetIdentityTokenLifetime(TimeSpan? lifetime)
=> Configure(options => options.IdentityTokenLifetime = lifetime); => Configure(options => options.IdentityTokenLifetime = lifetime);
/// <summary> /// <summary>
@ -1690,7 +1683,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="lifetime">The refresh token lifetime.</param> /// <param name="lifetime">The refresh token lifetime.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetRefreshTokenLifetime([CanBeNull] TimeSpan? lifetime) public OpenIddictServerBuilder SetRefreshTokenLifetime(TimeSpan? lifetime)
=> Configure(options => options.RefreshTokenLifetime = lifetime); => Configure(options => options.RefreshTokenLifetime = lifetime);
/// <summary> /// <summary>
@ -1700,7 +1693,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="lifetime">The authorization code lifetime.</param> /// <param name="lifetime">The authorization code lifetime.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetUserCodeLifetime([CanBeNull] TimeSpan? lifetime) public OpenIddictServerBuilder SetUserCodeLifetime(TimeSpan? lifetime)
=> Configure(options => options.UserCodeLifetime = lifetime); => Configure(options => options.UserCodeLifetime = lifetime);
/// <summary> /// <summary>
@ -1709,7 +1702,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <param name="address">The issuer address.</param> /// <param name="address">The issuer address.</param>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder SetIssuer([NotNull] Uri address) public OpenIddictServerBuilder SetIssuer(Uri address)
{ {
if (address == null) if (address == null)
{ {
@ -1756,7 +1749,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="obj">The object to compare with the current object.</param> /// <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> /// <returns><c>true</c> if the specified object is equal to the current object; otherwise, false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([CanBeNull] object obj) => base.Equals(obj); public override bool Equals(object? obj) => base.Equals(obj);
/// <summary> /// <summary>
/// Serves as the default hash function. /// Serves as the default hash function.
@ -1770,6 +1763,6 @@ namespace Microsoft.Extensions.DependencyInjection
/// </summary> /// </summary>
/// <returns>A string that represents the current object.</returns> /// <returns>A string that represents the current object.</returns>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString(); public override string? ToString() => base.ToString();
} }
} }

5
src/OpenIddict.Server/OpenIddictServerConfiguration.cs

@ -7,7 +7,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
@ -28,7 +27,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param> /// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param> /// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictServerOptions options) public void PostConfigure(string name, OpenIddictServerOptions options)
{ {
if (options == null) if (options == null)
{ {
@ -300,7 +299,7 @@ namespace OpenIddict.Server
(SecurityKey _, SecurityKey _) => 0 (SecurityKey _, SecurityKey _) => 0
}; };
static string GetKeyIdentifier(SecurityKey key) static string? GetKeyIdentifier(SecurityKey key)
{ {
// When no key identifier can be retrieved from the security keys, a value is automatically // When no key identifier can be retrieved from the security keys, a value is automatically
// inferred from the hexadecimal representation of the certificate thumbprint (SHA-1) // inferred from the hexadecimal representation of the certificate thumbprint (SHA-1)

9
src/OpenIddict.Server/OpenIddictServerDispatcher.cs

@ -7,7 +7,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.OpenIddictServerEvents;
@ -25,16 +24,16 @@ namespace OpenIddict.Server
/// Creates a new instance of the <see cref="OpenIddictServerDispatcher"/> class. /// Creates a new instance of the <see cref="OpenIddictServerDispatcher"/> class.
/// </summary> /// </summary>
public OpenIddictServerDispatcher( public OpenIddictServerDispatcher(
[NotNull] ILogger<OpenIddictServerDispatcher> logger, ILogger<OpenIddictServerDispatcher> logger,
[NotNull] IOptionsMonitor<OpenIddictServerOptions> options, IOptionsMonitor<OpenIddictServerOptions> options,
[NotNull] IServiceProvider provider) IServiceProvider provider)
{ {
_logger = logger; _logger = logger;
_options = options; _options = options;
_provider = provider; _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) if (context == null)
{ {

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

@ -6,7 +6,7 @@
using System; using System;
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations; using OpenIddict.Abstractions;
using SR = OpenIddict.Abstractions.OpenIddictResources; using SR = OpenIddict.Abstractions.OpenIddictResources;
namespace OpenIddict.Server namespace OpenIddict.Server
@ -22,10 +22,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractAuthorizationRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractAuthorizationRequestContext"/> class.
/// </summary> /// </summary>
public ExtractAuthorizationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractAuthorizationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request or <c>null</c> if it was extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -37,22 +46,31 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateAuthorizationRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateAuthorizationRequestContext"/> class.
/// </summary> /// </summary>
public ValidateAuthorizationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateAuthorizationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
// Infer the redirect_uri from the value specified by the client application. // Infer the redirect_uri from the value specified by the client application.
=> RedirectUri = Request?.RedirectUri; => RedirectUri = Request?.RedirectUri;
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets the client_id specified by the client application. /// Gets the client_id specified by the client application.
/// </summary> /// </summary>
public string ClientId => Request.ClientId; public string? ClientId => Request?.ClientId;
/// <summary> /// <summary>
/// Gets the redirect_uri specified by the client application. /// Gets the redirect_uri specified by the client application.
/// If it's not provided by the client, it must be set by /// If it's not provided by the client, it must be set by
/// the user code by calling <see cref="SetRedirectUri(string)"/>. /// the user code by calling <see cref="SetRedirectUri(string)"/>.
/// </summary> /// </summary>
public string RedirectUri { get; private set; } public string? RedirectUri { get; private set; }
/// <summary> /// <summary>
/// Populates the <see cref="RedirectUri"/> property with the specified redirect_uri. /// Populates the <see cref="RedirectUri"/> property with the specified redirect_uri.
@ -67,7 +85,7 @@ namespace OpenIddict.Server
// Don't allow validation to alter the redirect_uri parameter extracted // Don't allow validation to alter the redirect_uri parameter extracted
// from the request if the address was explicitly provided by the client. // from the request if the address was explicitly provided by the client.
if (!string.IsNullOrEmpty(Request.RedirectUri) && if (!string.IsNullOrEmpty(Request?.RedirectUri) &&
!string.Equals(Request.RedirectUri, address, StringComparison.Ordinal)) !string.Equals(Request.RedirectUri, address, StringComparison.Ordinal))
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1100)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1100));
@ -86,11 +104,20 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleAuthorizationRequestContext"/> class. /// Creates a new instance of the <see cref="HandleAuthorizationRequestContext"/> class.
/// </summary> /// </summary>
public HandleAuthorizationRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleAuthorizationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal. /// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary> /// </summary>
@ -106,36 +133,54 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyAuthorizationResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyAuthorizationResponseContext"/> class.
/// </summary> /// </summary>
public ApplyAuthorizationResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyAuthorizationResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets or sets the security principal. /// Gets or sets the security principal.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets the access code expected to /// Gets the access code expected to
/// be returned to the client application. /// be returned to the client application.
/// Depending on the flow, it may be null. /// Depending on the flow, it may be null.
/// </summary> /// </summary>
public string AccessToken => Response.AccessToken; public string? AccessToken => Response?.AccessToken;
/// <summary> /// <summary>
/// Gets the authorization code expected to /// Gets the authorization code expected to
/// be returned to the client application. /// be returned to the client application.
/// Depending on the flow, it may be null. /// Depending on the flow, it may be null.
/// </summary> /// </summary>
public string AuthorizationCode => Response.Code; public string? AuthorizationCode => Response?.Code;
/// <summary> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response?.Error;
/// <summary> /// <summary>
/// Gets or sets the callback URL the user agent will be redirected to, if applicable. /// Gets or sets the callback URL the user agent will be redirected to, if applicable.
@ -143,13 +188,13 @@ namespace OpenIddict.Server
/// and extreme caution must be taken to ensure the user agent is not redirected to /// and extreme caution must be taken to ensure the user agent is not redirected to
/// an untrusted address, which would result in an "open redirection" vulnerability. /// an untrusted address, which would result in an "open redirection" vulnerability.
/// </summary> /// </summary>
public string RedirectUri { get; set; } public string? RedirectUri { get; set; }
/// <summary> /// <summary>
/// Gets or sets the response mode used to redirect the user agent, if applicable. /// Gets or sets the response mode used to redirect the user agent, if applicable.
/// Note: manually changing the value of this property is generally not recommended. /// Note: manually changing the value of this property is generally not recommended.
/// </summary> /// </summary>
public string ResponseMode { get; set; } public string? ResponseMode { get; set; }
} }
} }
} }

114
src/OpenIddict.Server/OpenIddictServerEvents.Device.cs

@ -5,7 +5,7 @@
*/ */
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations; using OpenIddict.Abstractions;
namespace OpenIddict.Server namespace OpenIddict.Server
{ {
@ -20,10 +20,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractDeviceRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractDeviceRequestContext"/> class.
/// </summary> /// </summary>
public ExtractDeviceRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractDeviceRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -35,10 +44,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateDeviceRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateDeviceRequestContext"/> class.
/// </summary> /// </summary>
public ValidateDeviceRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateDeviceRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -50,10 +68,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleDeviceRequestContext"/> class. /// Creates a new instance of the <see cref="HandleDeviceRequestContext"/> class.
/// </summary> /// </summary>
public HandleDeviceRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleDeviceRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -64,17 +91,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyDeviceResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyDeviceResponseContext"/> class.
/// </summary> /// </summary>
public ApplyDeviceResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyDeviceResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
/// <summary> /// <summary>
@ -86,10 +131,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractVerificationRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractVerificationRequestContext"/> class.
/// </summary> /// </summary>
public ExtractVerificationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractVerificationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -101,15 +155,24 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateVerificationRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateVerificationRequestContext"/> class.
/// </summary> /// </summary>
public ValidateVerificationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateVerificationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the user code. /// Gets or sets the security principal extracted from the user code.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
} }
/// <summary> /// <summary>
@ -121,10 +184,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleVerificationRequestContext"/> class. /// Creates a new instance of the <see cref="HandleVerificationRequestContext"/> class.
/// </summary> /// </summary>
public HandleVerificationRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleVerificationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -135,17 +207,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyVerificationResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyVerificationResponseContext"/> class.
/// </summary> /// </summary>
public ApplyVerificationResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyVerificationResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
} }
} }

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

@ -6,7 +6,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
@ -23,10 +22,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractConfigurationRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractConfigurationRequestContext"/> class.
/// </summary> /// </summary>
public ExtractConfigurationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractConfigurationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -38,10 +46,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateConfigurationRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateConfigurationRequestContext"/> class.
/// </summary> /// </summary>
public ValidateConfigurationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateConfigurationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -53,11 +70,20 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleConfigurationRequestContext"/> class. /// Creates a new instance of the <see cref="HandleConfigurationRequestContext"/> class.
/// </summary> /// </summary>
public HandleConfigurationRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleConfigurationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets the additional parameters returned to the client application. /// Gets the additional parameters returned to the client application.
/// </summary> /// </summary>
@ -67,42 +93,42 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Gets or sets the authorization endpoint address. /// Gets or sets the authorization endpoint address.
/// </summary> /// </summary>
public Uri AuthorizationEndpoint { get; set; } public Uri? AuthorizationEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the JWKS endpoint address. /// Gets or sets the JWKS endpoint address.
/// </summary> /// </summary>
public Uri CryptographyEndpoint { get; set; } public Uri? CryptographyEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the device endpoint address. /// Gets or sets the device endpoint address.
/// </summary> /// </summary>
public Uri DeviceEndpoint { get; set; } public Uri? DeviceEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the introspection endpoint address. /// Gets or sets the introspection endpoint address.
/// </summary> /// </summary>
public Uri IntrospectionEndpoint { get; set; } public Uri? IntrospectionEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the logout endpoint address. /// Gets or sets the logout endpoint address.
/// </summary> /// </summary>
public Uri LogoutEndpoint { get; set; } public Uri? LogoutEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the revocation endpoint address. /// Gets or sets the revocation endpoint address.
/// </summary> /// </summary>
public Uri RevocationEndpoint { get; set; } public Uri? RevocationEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the token endpoint address. /// Gets or sets the token endpoint address.
/// </summary> /// </summary>
public Uri TokenEndpoint { get; set; } public Uri? TokenEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets or sets the userinfo endpoint address. /// Gets or sets the userinfo endpoint address.
/// </summary> /// </summary>
public Uri UserinfoEndpoint { get; set; } public Uri? UserinfoEndpoint { get; set; }
/// <summary> /// <summary>
/// Gets the list of claims supported by the authorization server. /// Gets the list of claims supported by the authorization server.
@ -178,17 +204,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyConfigurationResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyConfigurationResponseContext"/> class.
/// </summary> /// </summary>
public ApplyConfigurationResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyConfigurationResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
/// <summary> /// <summary>
@ -200,10 +244,28 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractCryptographyRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractCryptographyRequestContext"/> class.
/// </summary> /// </summary>
public ExtractCryptographyRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractCryptographyRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </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> /// <summary>
@ -215,10 +277,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateCryptographyRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateCryptographyRequestContext"/> class.
/// </summary> /// </summary>
public ValidateCryptographyRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateCryptographyRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -230,11 +301,20 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleCryptographyRequestContext"/> class. /// Creates a new instance of the <see cref="HandleCryptographyRequestContext"/> class.
/// </summary> /// </summary>
public HandleCryptographyRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleCryptographyRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets the list of JSON Web Keys exposed by the JWKS endpoint. /// Gets the list of JSON Web Keys exposed by the JWKS endpoint.
/// </summary> /// </summary>
@ -249,17 +329,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyCryptographyResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyCryptographyResponseContext"/> class.
/// </summary> /// </summary>
public ApplyCryptographyResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyCryptographyResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
} }
} }

61
src/OpenIddict.Server/OpenIddictServerEvents.Exchange.cs

@ -5,7 +5,7 @@
*/ */
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations; using OpenIddict.Abstractions;
namespace OpenIddict.Server namespace OpenIddict.Server
{ {
@ -20,10 +20,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractTokenRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractTokenRequestContext"/> class.
/// </summary> /// </summary>
public ExtractTokenRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractTokenRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -35,16 +44,25 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateTokenRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateTokenRequestContext"/> class.
/// </summary> /// </summary>
public ValidateTokenRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateTokenRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the authorization /// Gets or sets the security principal extracted from the authorization
/// code or the refresh token, if applicable to the current token request. /// code or the refresh token, if applicable to the current token request.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
} }
/// <summary> /// <summary>
@ -56,11 +74,20 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleTokenRequestContext"/> class. /// Creates a new instance of the <see cref="HandleTokenRequestContext"/> class.
/// </summary> /// </summary>
public HandleTokenRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleTokenRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal. /// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary> /// </summary>
@ -76,22 +103,40 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyTokenResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyTokenResponseContext"/> class.
/// </summary> /// </summary>
public ApplyTokenResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyTokenResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets or sets the security principal used to forge the token response. /// Gets or sets the security principal used to forge the token response.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
} }
} }

77
src/OpenIddict.Server/OpenIddictServerEvents.Introspection.cs

@ -7,7 +7,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
namespace OpenIddict.Server namespace OpenIddict.Server
@ -23,10 +22,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractIntrospectionRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractIntrospectionRequestContext"/> class.
/// </summary> /// </summary>
public ExtractIntrospectionRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractIntrospectionRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -38,21 +46,30 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateIntrospectionRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateIntrospectionRequestContext"/> class.
/// </summary> /// </summary>
public ValidateIntrospectionRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateIntrospectionRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets the optional token_type_hint parameter extracted from the /// Gets the optional token_type_hint parameter extracted from the
/// introspection request, or <c>null</c> if it cannot be found. /// introspection request, or <c>null</c> if it cannot be found.
/// </summary> /// </summary>
public string TokenTypeHint => Request.TokenTypeHint; public string? TokenTypeHint => Request?.TokenTypeHint;
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the introspected token, if available. /// Gets or sets the security principal extracted from the introspected token, if available.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
} }
/// <summary> /// <summary>
@ -64,15 +81,24 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleIntrospectionRequestContext"/> class. /// Creates a new instance of the <see cref="HandleIntrospectionRequestContext"/> class.
/// </summary> /// </summary>
public HandleIntrospectionRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleIntrospectionRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the introspected token. /// Gets or sets the security principal extracted from the introspected token.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets the additional claims returned to the caller. /// Gets the additional claims returned to the caller.
@ -87,10 +113,9 @@ namespace OpenIddict.Server
public HashSet<string> Audiences { get; } = new HashSet<string>(StringComparer.Ordinal); public HashSet<string> Audiences { get; } = new HashSet<string>(StringComparer.Ordinal);
/// <summary> /// <summary>
/// Gets or sets the "client_id" claim /// Gets or sets the "client_id" claim returned to the caller, if applicable.
/// returned to the caller, if applicable.
/// </summary> /// </summary>
public string ClientId { get; set; } public string? ClientId { get; set; }
/// <summary> /// <summary>
/// Gets or sets the "exp" claim /// Gets or sets the "exp" claim
@ -120,31 +145,31 @@ namespace OpenIddict.Server
/// Gets or sets the "sub" claim /// Gets or sets the "sub" claim
/// returned to the caller, if applicable. /// returned to the caller, if applicable.
/// </summary> /// </summary>
public string Subject { get; set; } public string? Subject { get; set; }
/// <summary> /// <summary>
/// Gets or sets the "jti" claim /// Gets or sets the "jti" claim
/// returned to the caller, if applicable. /// returned to the caller, if applicable.
/// </summary> /// </summary>
public string TokenId { get; set; } public string? TokenId { get; set; }
/// <summary> /// <summary>
/// Gets or sets the "token_type" claim /// Gets or sets the "token_type" claim
/// returned to the caller, if applicable. /// returned to the caller, if applicable.
/// </summary> /// </summary>
public string TokenType { get; set; } public string? TokenType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the "token_usage" claim /// Gets or sets the "token_usage" claim
/// returned to the caller, if applicable. /// returned to the caller, if applicable.
/// </summary> /// </summary>
public string TokenUsage { get; set; } public string? TokenUsage { get; set; }
/// <summary> /// <summary>
/// Gets or sets the "username" claim /// Gets or sets the "username" claim
/// returned to the caller, if applicable. /// returned to the caller, if applicable.
/// </summary> /// </summary>
public string Username { get; set; } public string? Username { get; set; }
} }
/// <summary> /// <summary>
@ -155,17 +180,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyIntrospectionResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyIntrospectionResponseContext"/> class.
/// </summary> /// </summary>
public ApplyIntrospectionResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyIntrospectionResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
} }
} }

63
src/OpenIddict.Server/OpenIddictServerEvents.Revocation.cs

@ -7,7 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations; using OpenIddict.Abstractions;
namespace OpenIddict.Server namespace OpenIddict.Server
{ {
@ -22,10 +22,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractRevocationRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractRevocationRequestContext"/> class.
/// </summary> /// </summary>
public ExtractRevocationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractRevocationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -37,21 +46,30 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateRevocationRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateRevocationRequestContext"/> class.
/// </summary> /// </summary>
public ValidateRevocationRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateRevocationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets the optional token_type_hint parameter extracted from the /// Gets the optional token_type_hint parameter extracted from the
/// revocation request, or <c>null</c> if it cannot be found. /// revocation request, or <c>null</c> if it cannot be found.
/// </summary> /// </summary>
public string TokenTypeHint => Request.TokenTypeHint; public string? TokenTypeHint => Request.TokenTypeHint;
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the revoked token, if available. /// Gets or sets the security principal extracted from the revoked token, if available.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
} }
/// <summary> /// <summary>
@ -63,15 +81,24 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleRevocationRequestContext"/> class. /// Creates a new instance of the <see cref="HandleRevocationRequestContext"/> class.
/// </summary> /// </summary>
public HandleRevocationRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleRevocationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the revoked token. /// Gets or sets the security principal extracted from the revoked token.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets the authentication ticket. /// Gets the authentication ticket.
@ -88,17 +115,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyRevocationResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyRevocationResponseContext"/> class.
/// </summary> /// </summary>
public ApplyRevocationResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyRevocationResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
} }
} }

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

@ -5,7 +5,7 @@
*/ */
using System; using System;
using JetBrains.Annotations; using OpenIddict.Abstractions;
using SR = OpenIddict.Abstractions.OpenIddictResources; using SR = OpenIddict.Abstractions.OpenIddictResources;
namespace OpenIddict.Server namespace OpenIddict.Server
@ -21,10 +21,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractLogoutRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractLogoutRequestContext"/> class.
/// </summary> /// </summary>
public ExtractLogoutRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractLogoutRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -36,15 +45,24 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateLogoutRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateLogoutRequestContext"/> class.
/// </summary> /// </summary>
public ValidateLogoutRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateLogoutRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
// Infer the post_logout_redirect_uri from the value specified by the client application. // Infer the post_logout_redirect_uri from the value specified by the client application.
=> PostLogoutRedirectUri = Request?.PostLogoutRedirectUri; => PostLogoutRedirectUri = Request?.PostLogoutRedirectUri;
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets the post_logout_redirect_uri specified by the client application. /// Gets the post_logout_redirect_uri specified by the client application.
/// </summary> /// </summary>
public string PostLogoutRedirectUri { get; private set; } public string? PostLogoutRedirectUri { get; private set; }
/// <summary> /// <summary>
/// Populates the <see cref="PostLogoutRedirectUri"/> property with the specified redirect_uri. /// Populates the <see cref="PostLogoutRedirectUri"/> property with the specified redirect_uri.
@ -59,7 +77,7 @@ namespace OpenIddict.Server
// Don't allow validation to alter the post_logout_redirect_uri parameter extracted // Don't allow validation to alter the post_logout_redirect_uri parameter extracted
// from the request if the address was explicitly provided by the client application. // from the request if the address was explicitly provided by the client application.
if (!string.IsNullOrEmpty(Request.PostLogoutRedirectUri) && if (!string.IsNullOrEmpty(Request?.PostLogoutRedirectUri) &&
!string.Equals(Request.PostLogoutRedirectUri, address, StringComparison.Ordinal)) !string.Equals(Request.PostLogoutRedirectUri, address, StringComparison.Ordinal))
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1102)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1102));
@ -78,11 +96,20 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleLogoutRequestContext"/> class. /// Creates a new instance of the <see cref="HandleLogoutRequestContext"/> class.
/// </summary> /// </summary>
public HandleLogoutRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleLogoutRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets a boolean indicating whether a sign-out should be triggered. /// Gets a boolean indicating whether a sign-out should be triggered.
/// </summary> /// </summary>
@ -102,17 +129,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyLogoutResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyLogoutResponseContext"/> class.
/// </summary> /// </summary>
public ApplyLogoutResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyLogoutResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
/// <summary> /// <summary>
/// Gets or sets the callback URL the user agent will be redirected to, if applicable. /// Gets or sets the callback URL the user agent will be redirected to, if applicable.
@ -120,7 +165,7 @@ namespace OpenIddict.Server
/// and extreme caution must be taken to ensure the user agent is not redirected to /// and extreme caution must be taken to ensure the user agent is not redirected to
/// an untrusted address, which would result in an "open redirection" vulnerability. /// an untrusted address, which would result in an "open redirection" vulnerability.
/// </summary> /// </summary>
public string PostLogoutRedirectUri { get; set; } public string? PostLogoutRedirectUri { get; set; }
} }
} }
} }

78
src/OpenIddict.Server/OpenIddictServerEvents.Userinfo.cs

@ -8,7 +8,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Json; using System.Text.Json;
using JetBrains.Annotations;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
namespace OpenIddict.Server namespace OpenIddict.Server
@ -24,10 +23,19 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ExtractUserinfoRequestContext"/> class. /// Creates a new instance of the <see cref="ExtractUserinfoRequestContext"/> class.
/// </summary> /// </summary>
public ExtractUserinfoRequestContext([NotNull] OpenIddictServerTransaction transaction) public ExtractUserinfoRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request, or <c>null</c> if it wasn't extracted yet.
/// </summary>
public OpenIddictRequest? Request
{
get => Transaction.Request;
set => Transaction.Request = value;
}
} }
/// <summary> /// <summary>
@ -39,15 +47,24 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ValidateUserinfoRequestContext"/> class. /// Creates a new instance of the <see cref="ValidateUserinfoRequestContext"/> class.
/// </summary> /// </summary>
public ValidateUserinfoRequestContext([NotNull] OpenIddictServerTransaction transaction) public ValidateUserinfoRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the access token, if available. /// Gets or sets the security principal extracted from the access token, if available.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
} }
/// <summary> /// <summary>
@ -59,15 +76,24 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="HandleUserinfoRequestContext"/> class. /// Creates a new instance of the <see cref="HandleUserinfoRequestContext"/> class.
/// </summary> /// </summary>
public HandleUserinfoRequestContext([NotNull] OpenIddictServerTransaction transaction) public HandleUserinfoRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal extracted from the access token. /// Gets or sets the security principal extracted from the access token.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets the additional claims returned to the client application. /// Gets the additional claims returned to the client application.
@ -92,14 +118,14 @@ namespace OpenIddict.Server
/// Note: this value should only be populated if the "profile" /// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string BirthDate { get; set; } public string? BirthDate { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "email" claim. /// Gets or sets the value used for the "email" claim.
/// Note: this value should only be populated if the "email" /// Note: this value should only be populated if the "email"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string Email { get; set; } public string? Email { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "email_verified" claim. /// Gets or sets the value used for the "email_verified" claim.
@ -113,21 +139,21 @@ namespace OpenIddict.Server
/// Note: this value should only be populated if the "profile" /// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string FamilyName { get; set; } public string? FamilyName { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "given_name" claim. /// Gets or sets the value used for the "given_name" claim.
/// Note: this value should only be populated if the "profile" /// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string GivenName { get; set; } public string? GivenName { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "phone_number" claim. /// Gets or sets the value used for the "phone_number" claim.
/// Note: this value should only be populated if the "phone" /// Note: this value should only be populated if the "phone"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string PhoneNumber { get; set; } public string? PhoneNumber { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "phone_number_verified" claim. /// Gets or sets the value used for the "phone_number_verified" claim.
@ -141,27 +167,27 @@ namespace OpenIddict.Server
/// Note: this value should only be populated if the "profile" /// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string PreferredUsername { get; set; } public string? PreferredUsername { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "profile" claim. /// Gets or sets the value used for the "profile" claim.
/// Note: this value should only be populated if the "profile" /// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string Profile { get; set; } public string? Profile { get; set; }
/// <summary> /// <summary>
/// Gets or sets the unique value /// Gets or sets the unique value
/// used for the mandatory "sub" claim. /// used for the mandatory "sub" claim.
/// </summary> /// </summary>
public string Subject { get; set; } public string? Subject { get; set; }
/// <summary> /// <summary>
/// Gets or sets the value used for the "website" claim. /// Gets or sets the value used for the "website" claim.
/// Note: this value should only be populated if the "profile" /// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner. /// scope was requested and accepted by the resource owner.
/// </summary> /// </summary>
public string Website { get; set; } public string? Website { get; set; }
} }
/// <summary> /// <summary>
@ -172,17 +198,35 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ApplyUserinfoResponseContext"/> class. /// Creates a new instance of the <see cref="ApplyUserinfoResponseContext"/> class.
/// </summary> /// </summary>
public ApplyUserinfoResponseContext([NotNull] OpenIddictServerTransaction transaction) public ApplyUserinfoResponseContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets the error code returned to the client application. /// Gets the error code returned to the client application.
/// When the response indicates a successful response, /// When the response indicates a successful response,
/// this property returns <c>null</c>. /// this property returns <c>null</c>.
/// </summary> /// </summary>
public string Error => Response.Error; public string? Error => Response.Error;
} }
} }
} }

162
src/OpenIddict.Server/OpenIddictServerEvents.cs

@ -7,7 +7,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Security.Claims; using System.Security.Claims;
using JetBrains.Annotations;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
@ -25,7 +24,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="BaseContext"/> class. /// Creates a new instance of the <see cref="BaseContext"/> class.
/// </summary> /// </summary>
protected BaseContext([NotNull] OpenIddictServerTransaction transaction) protected BaseContext(OpenIddictServerTransaction transaction)
=> Transaction = transaction ?? throw new ArgumentNullException(nameof(transaction)); => Transaction = transaction ?? throw new ArgumentNullException(nameof(transaction));
/// <summary> /// <summary>
@ -36,7 +35,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Gets or sets the issuer address associated with the current transaction, if available. /// Gets or sets the issuer address associated with the current transaction, if available.
/// </summary> /// </summary>
public Uri Issuer public Uri? Issuer
{ {
get => Transaction.Issuer; get => Transaction.Issuer;
set => Transaction.Issuer = value; set => Transaction.Issuer = value;
@ -65,24 +64,6 @@ namespace OpenIddict.Server
/// Gets the OpenIddict server options. /// Gets the OpenIddict server options.
/// </summary> /// </summary>
public OpenIddictServerOptions Options => Transaction.Options; public OpenIddictServerOptions 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> /// <summary>
@ -94,7 +75,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="BaseRequestContext"/> class. /// Creates a new instance of the <see cref="BaseRequestContext"/> class.
/// </summary> /// </summary>
protected BaseRequestContext([NotNull] OpenIddictServerTransaction transaction) protected BaseRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
@ -133,7 +114,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="BaseValidatingClientContext"/> class. /// Creates a new instance of the <see cref="BaseValidatingClientContext"/> class.
/// </summary> /// </summary>
protected BaseValidatingClientContext([NotNull] OpenIddictServerTransaction transaction) protected BaseValidatingClientContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
@ -143,14 +124,14 @@ namespace OpenIddict.Server
/// The authorization server application is responsible for /// The authorization server application is responsible for
/// validating this value to ensure it identifies a registered client. /// validating this value to ensure it identifies a registered client.
/// </summary> /// </summary>
public string ClientId => (string) Request[OpenIddictConstants.Parameters.ClientId]; public string? ClientId => Transaction.Request?.ClientId;
/// <summary> /// <summary>
/// Gets the "client_secret" parameter for the current request. /// Gets the "client_secret" parameter for the current request.
/// The authorization server application is responsible for /// The authorization server application is responsible for
/// validating this value to ensure it identifies a registered client. /// validating this value to ensure it identifies a registered client.
/// </summary> /// </summary>
public string ClientSecret => (string) Request[OpenIddictConstants.Parameters.ClientSecret]; public string? ClientSecret => Transaction.Request?.ClientSecret;
} }
/// <summary> /// <summary>
@ -162,7 +143,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="BaseValidatingContext"/> class. /// Creates a new instance of the <see cref="BaseValidatingContext"/> class.
/// </summary> /// </summary>
protected BaseValidatingContext([NotNull] OpenIddictServerTransaction transaction) protected BaseValidatingContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
@ -175,17 +156,17 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Gets or sets the "error" parameter returned to the client application. /// Gets or sets the "error" parameter returned to the client application.
/// </summary> /// </summary>
public string Error { get; private set; } public string? Error { get; private set; }
/// <summary> /// <summary>
/// Gets or sets the "error_description" parameter returned to the client application. /// Gets or sets the "error_description" parameter returned to the client application.
/// </summary> /// </summary>
public string ErrorDescription { get; private set; } public string? ErrorDescription { get; private set; }
/// <summary> /// <summary>
/// Gets or sets the "error_uri" parameter returned to the client application. /// Gets or sets the "error_uri" parameter returned to the client application.
/// </summary> /// </summary>
public string ErrorUri { get; private set; } public string? ErrorUri { get; private set; }
/// <summary> /// <summary>
/// Rejects the request. /// Rejects the request.
@ -196,7 +177,7 @@ namespace OpenIddict.Server
/// Rejects the request. /// Rejects the request.
/// </summary> /// </summary>
/// <param name="error">The "error" parameter returned to the client application.</param> /// <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; Error = error;
@ -208,7 +189,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
/// <param name="error">The "error" parameter returned to the client application.</param> /// <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="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; Error = error;
ErrorDescription = description; ErrorDescription = description;
@ -222,7 +203,7 @@ namespace OpenIddict.Server
/// <param name="error">The "error" parameter returned to the client application.</param> /// <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="description">The "error_description" parameter returned to the client application.</param>
/// <param name="uri">The "error_uri" 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; Error = error;
ErrorDescription = description; ErrorDescription = description;
@ -241,7 +222,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="BaseValidatingTicketContext"/> class. /// Creates a new instance of the <see cref="BaseValidatingTicketContext"/> class.
/// </summary> /// </summary>
protected BaseValidatingTicketContext([NotNull] OpenIddictServerTransaction transaction) protected BaseValidatingTicketContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
@ -249,12 +230,12 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Gets or sets the security principal. /// Gets or sets the security principal.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets the client identifier, or <c>null</c> if the client application is unknown. /// Gets the client identifier, or <c>null</c> if the client application is unknown.
/// </summary> /// </summary>
public string ClientId => Request.ClientId; public string? ClientId => Transaction.Request?.ClientId;
} }
/// <summary> /// <summary>
@ -265,7 +246,7 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ProcessRequestContext"/> class. /// Creates a new instance of the <see cref="ProcessRequestContext"/> class.
/// </summary> /// </summary>
public ProcessRequestContext([NotNull] OpenIddictServerTransaction transaction) public ProcessRequestContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
@ -279,10 +260,28 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ProcessErrorContext"/> class. /// Creates a new instance of the <see cref="ProcessErrorContext"/> class.
/// </summary> /// </summary>
public ProcessErrorContext([NotNull] OpenIddictServerTransaction transaction) public ProcessErrorContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
@ -293,25 +292,34 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ProcessAuthenticationContext"/> class. /// Creates a new instance of the <see cref="ProcessAuthenticationContext"/> class.
/// </summary> /// </summary>
public ProcessAuthenticationContext([NotNull] OpenIddictServerTransaction transaction) public ProcessAuthenticationContext(OpenIddictServerTransaction transaction)
: base(transaction) : base(transaction)
{ {
} }
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary> /// <summary>
/// Gets or sets the security principal. /// Gets or sets the security principal.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; set; } public ClaimsPrincipal? Principal { get; set; }
/// <summary> /// <summary>
/// Gets or sets the token to validate. /// Gets or sets the token to validate.
/// </summary> /// </summary>
public string Token { get; set; } public string? Token { get; set; }
/// <summary> /// <summary>
/// Gets or sets the expected type of the token. /// Gets or sets the expected type of the token.
/// </summary> /// </summary>
public string TokenType { get; set; } public string? TokenType { get; set; }
} }
/// <summary> /// <summary>
@ -322,10 +330,28 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ProcessChallengeContext"/> class. /// Creates a new instance of the <see cref="ProcessChallengeContext"/> class.
/// </summary> /// </summary>
public ProcessChallengeContext([NotNull] OpenIddictServerTransaction transaction) public ProcessChallengeContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
@ -336,11 +362,29 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ProcessSignInContext"/> class. /// Creates a new instance of the <see cref="ProcessSignInContext"/> class.
/// </summary> /// </summary>
public ProcessSignInContext([NotNull] OpenIddictServerTransaction transaction) public ProcessSignInContext(OpenIddictServerTransaction transaction)
: base(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> /// <summary>
/// Gets or sets a boolean indicating whether an access token /// Gets or sets a boolean indicating whether an access token
/// should be returned to the client application. /// should be returned to the client application.
@ -393,37 +437,37 @@ namespace OpenIddict.Server
/// Gets or sets the principal containing the claims that /// Gets or sets the principal containing the claims that
/// will be used to create the access token, if applicable. /// will be used to create the access token, if applicable.
/// </summary> /// </summary>
public ClaimsPrincipal AccessTokenPrincipal { get; set; } public ClaimsPrincipal? AccessTokenPrincipal { get; set; }
/// <summary> /// <summary>
/// Gets or sets the principal containing the claims that /// Gets or sets the principal containing the claims that
/// will be used to create the authorization code, if applicable. /// will be used to create the authorization code, if applicable.
/// </summary> /// </summary>
public ClaimsPrincipal AuthorizationCodePrincipal { get; set; } public ClaimsPrincipal? AuthorizationCodePrincipal { get; set; }
/// <summary> /// <summary>
/// Gets or sets the principal containing the claims that /// Gets or sets the principal containing the claims that
/// will be used to create the device code, if applicable. /// will be used to create the device code, if applicable.
/// </summary> /// </summary>
public ClaimsPrincipal DeviceCodePrincipal { get; set; } public ClaimsPrincipal? DeviceCodePrincipal { get; set; }
/// <summary> /// <summary>
/// Gets or sets the principal containing the claims that /// Gets or sets the principal containing the claims that
/// will be used to create the identity token, if applicable. /// will be used to create the identity token, if applicable.
/// </summary> /// </summary>
public ClaimsPrincipal IdentityTokenPrincipal { get; set; } public ClaimsPrincipal? IdentityTokenPrincipal { get; set; }
/// <summary> /// <summary>
/// Gets or sets the principal containing the claims that /// Gets or sets the principal containing the claims that
/// will be used to create the refresh token, if applicable. /// will be used to create the refresh token, if applicable.
/// </summary> /// </summary>
public ClaimsPrincipal RefreshTokenPrincipal { get; set; } public ClaimsPrincipal? RefreshTokenPrincipal { get; set; }
/// <summary> /// <summary>
/// Gets or sets the principal containing the claims that /// Gets or sets the principal containing the claims that
/// will be used to create the user code, if applicable. /// will be used to create the user code, if applicable.
/// </summary> /// </summary>
public ClaimsPrincipal UserCodePrincipal { get; set; } public ClaimsPrincipal? UserCodePrincipal { get; set; }
} }
/// <summary> /// <summary>
@ -434,10 +478,28 @@ namespace OpenIddict.Server
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ProcessSignOutContext"/> class. /// Creates a new instance of the <see cref="ProcessSignOutContext"/> class.
/// </summary> /// </summary>
public ProcessSignOutContext([NotNull] OpenIddictServerTransaction transaction) public ProcessSignOutContext(OpenIddictServerTransaction transaction)
: base(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.Server/OpenIddictServerExtensions.cs

@ -6,7 +6,6 @@
using System; using System;
using System.Linq; using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging.Abstractions; 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> /// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks> /// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public static OpenIddictServerBuilder AddServer([NotNull] this OpenIddictBuilder builder) public static OpenIddictServerBuilder AddServer(this OpenIddictBuilder builder)
{ {
if (builder == null) if (builder == null)
{ {
@ -106,9 +105,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The configuration delegate used to configure the server services.</param> /// <param name="configuration">The configuration delegate used to configure the server services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks> /// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
public static OpenIddictBuilder AddServer( public static OpenIddictBuilder AddServer(this OpenIddictBuilder builder, Action<OpenIddictServerBuilder> configuration)
[NotNull] this OpenIddictBuilder builder,
[NotNull] Action<OpenIddictServerBuilder> configuration)
{ {
if (builder == null) if (builder == null)
{ {

7
src/OpenIddict.Server/OpenIddictServerFactory.cs

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

5
src/OpenIddict.Server/OpenIddictServerHandler.cs

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

15
src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs

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

65
src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs

@ -7,7 +7,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.OpenIddictServerEvents;
namespace OpenIddict.Server namespace OpenIddict.Server
@ -20,7 +19,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireAccessTokenIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext> public class RequireAccessTokenIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] ProcessSignInContext context) public ValueTask<bool> IsActiveAsync(ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -36,7 +35,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireAuthorizationCodeIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext> public class RequireAuthorizationCodeIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] ProcessSignInContext context) public ValueTask<bool> IsActiveAsync(ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -52,7 +51,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireAuthorizationRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireAuthorizationRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -68,7 +67,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireAuthorizationStorageEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireAuthorizationStorageEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -84,14 +83,14 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireClientIdParameter : IOpenIddictServerHandlerFilter<BaseContext> public class RequireClientIdParameter : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
return new ValueTask<bool>(!string.IsNullOrEmpty(context.Request.ClientId)); return new ValueTask<bool>(!string.IsNullOrEmpty(context.Transaction.Request?.ClientId));
} }
} }
@ -100,7 +99,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireConfigurationRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireConfigurationRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -116,7 +115,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireCryptographyRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireCryptographyRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -132,7 +131,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireDegradedModeDisabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireDegradedModeDisabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -148,7 +147,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireDeviceCodeIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext> public class RequireDeviceCodeIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] ProcessSignInContext context) public ValueTask<bool> IsActiveAsync(ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -164,7 +163,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireDeviceRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireDeviceRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -180,7 +179,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireEndpointPermissionsEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireEndpointPermissionsEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -196,7 +195,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireGrantTypePermissionsEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireGrantTypePermissionsEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -212,7 +211,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireIdentityTokenIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext> public class RequireIdentityTokenIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] ProcessSignInContext context) public ValueTask<bool> IsActiveAsync(ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -228,7 +227,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireIntrospectionRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireIntrospectionRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -244,7 +243,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireLogoutRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireLogoutRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -260,14 +259,14 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequirePostLogoutRedirectUriParameter : IOpenIddictServerHandlerFilter<BaseContext> public class RequirePostLogoutRedirectUriParameter : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
return new ValueTask<bool>(!string.IsNullOrEmpty(context.Request.PostLogoutRedirectUri)); return new ValueTask<bool>(!string.IsNullOrEmpty(context.Transaction.Request?.PostLogoutRedirectUri));
} }
} }
@ -276,7 +275,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireReferenceAccessTokensEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireReferenceAccessTokensEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -292,7 +291,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireReferenceRefreshTokensEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireReferenceRefreshTokensEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -308,7 +307,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireRefreshTokenIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext> public class RequireRefreshTokenIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] ProcessSignInContext context) public ValueTask<bool> IsActiveAsync(ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -324,7 +323,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireRevocationRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireRevocationRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -340,7 +339,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireRollingTokensDisabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireRollingTokensDisabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -356,7 +355,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireRollingRefreshTokensEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireRollingRefreshTokensEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -372,7 +371,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireScopePermissionsEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireScopePermissionsEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -388,7 +387,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireScopeValidationEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireScopeValidationEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -404,7 +403,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireSlidingRefreshTokenExpirationEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireSlidingRefreshTokenExpirationEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -420,7 +419,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireTokenRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireTokenRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -436,7 +435,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireTokenStorageEnabled : IOpenIddictServerHandlerFilter<BaseContext> public class RequireTokenStorageEnabled : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -452,7 +451,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireUserCodeIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext> public class RequireUserCodeIncluded : IOpenIddictServerHandlerFilter<ProcessSignInContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] ProcessSignInContext context) public ValueTask<bool> IsActiveAsync(ProcessSignInContext context)
{ {
if (context == null) if (context == null)
{ {
@ -468,7 +467,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireUserinfoRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireUserinfoRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -484,7 +483,7 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public class RequireVerificationRequest : IOpenIddictServerHandlerFilter<BaseContext> public class RequireVerificationRequest : IOpenIddictServerHandlerFilter<BaseContext>
{ {
public ValueTask<bool> IsActiveAsync([NotNull] BaseContext context) public ValueTask<bool> IsActiveAsync(BaseContext context)
{ {
if (context == null) if (context == null)
{ {

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

@ -7,9 +7,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
@ -71,7 +71,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractAuthorizationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractAuthorizationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -85,14 +85,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -139,7 +133,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateAuthorizationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateAuthorizationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -153,14 +147,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -172,7 +160,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the redirect_uri without triggering a new validation process. // that want to access the redirect_uri without triggering a new validation process.
context.Transaction.SetProperty(typeof(ValidateAuthorizationRequestContext).FullName, notification); context.Transaction.SetProperty(typeof(ValidateAuthorizationRequestContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -211,7 +199,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleAuthorizationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleAuthorizationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -225,14 +213,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -306,7 +288,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyAuthorizationResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyAuthorizationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -320,14 +302,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -368,14 +344,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -413,14 +383,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -458,14 +422,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -504,14 +462,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -547,7 +499,7 @@ namespace OpenIddict.Server
// To ensure relative redirect_uris are correctly rejected on these platforms, // To ensure relative redirect_uris are correctly rejected on these platforms,
// an additional check using IsWellFormedOriginalString() is made here. // an additional check using IsWellFormedOriginalString() is made here.
// See https://github.com/dotnet/corefx/issues/22098 for more information. // See https://github.com/dotnet/corefx/issues/22098 for more information.
if (!Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out Uri uri) || !uri.IsWellFormedOriginalString()) if (!Uri.TryCreate(context.RedirectUri, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7034), Parameters.RedirectUri, context.RedirectUri); context.Logger.LogError(SR.GetResourceString(SR.ID7034), Parameters.RedirectUri, context.RedirectUri);
@ -591,14 +543,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -650,14 +596,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -736,14 +676,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -791,14 +725,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -845,14 +773,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -892,14 +814,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -990,7 +906,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1004,20 +920,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1043,7 +955,7 @@ namespace OpenIddict.Server
public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientType([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1057,20 +969,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1105,7 +1013,7 @@ namespace OpenIddict.Server
public ValidateClientRedirectUri() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientRedirectUri() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientRedirectUri([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientRedirectUri(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1119,20 +1027,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1184,7 +1088,7 @@ namespace OpenIddict.Server
public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopes([NotNull] IOpenIddictScopeManager scopeManager) public ValidateScopes(IOpenIddictScopeManager scopeManager)
=> _scopeManager = scopeManager; => _scopeManager = scopeManager;
/// <summary> /// <summary>
@ -1199,14 +1103,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1221,7 +1119,11 @@ namespace OpenIddict.Server
{ {
await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray())) await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray()))
{ {
scopes.Remove(await _scopeManager.GetNameAsync(scope)); var name = await _scopeManager.GetNameAsync(scope);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
}
} }
} }
@ -1249,7 +1151,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1264,20 +1166,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1308,7 +1206,7 @@ namespace OpenIddict.Server
public ValidateGrantTypePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateGrantTypePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateGrantTypePermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateGrantTypePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1323,20 +1221,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1409,7 +1303,7 @@ namespace OpenIddict.Server
public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopePermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateScopePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1424,20 +1318,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1479,7 +1369,7 @@ namespace OpenIddict.Server
public ValidateProofKeyForCodeExchangeRequirement() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateProofKeyForCodeExchangeRequirement() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateProofKeyForCodeExchangeRequirement([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateProofKeyForCodeExchangeRequirement(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1493,20 +1383,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
/// </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] ValidateAuthorizationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
// If a code_challenge was provided, the request is always considered valid, // If a code_challenge was provided, the request is always considered valid,
// whether the proof key for code exchange requirement is enforced or not. // whether the proof key for code exchange requirement is enforced or not.
if (!string.IsNullOrEmpty(context.Request.CodeChallenge)) if (!string.IsNullOrEmpty(context.Request.CodeChallenge))
@ -1549,14 +1435,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1569,7 +1449,7 @@ namespace OpenIddict.Server
} }
var notification = context.Transaction.GetProperty<ValidateAuthorizationRequestContext>( var notification = context.Transaction.GetProperty<ValidateAuthorizationRequestContext>(
typeof(ValidateAuthorizationRequestContext).FullName); typeof(ValidateAuthorizationRequestContext).FullName!);
// Note: at this stage, the validated redirect URI property may be null (e.g if an error // Note: at this stage, the validated redirect URI property may be null (e.g if an error
// is returned from the ExtractAuthorizationRequest/ValidateAuthorizationRequest events). // is returned from the ExtractAuthorizationRequest/ValidateAuthorizationRequest events).
@ -1598,14 +1478,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1646,14 +1520,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
/// </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] ApplyAuthorizationResponseContext context)
{ {
if (context == null) if (context == null)
{ {

224
src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs

@ -7,9 +7,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
@ -69,7 +69,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractDeviceRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractDeviceRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -83,14 +83,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -137,7 +131,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateDeviceRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateDeviceRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -151,14 +145,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -200,7 +188,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleDeviceRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleDeviceRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -214,14 +202,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -256,7 +238,7 @@ namespace OpenIddict.Server
{ {
// Note: no authentication type is deliberately specified to represent an unauthenticated identity. // Note: no authentication type is deliberately specified to represent an unauthenticated identity.
var principal = new ClaimsPrincipal(new ClaimsIdentity()); var principal = new ClaimsPrincipal(new ClaimsIdentity());
principal.SetScopes(context.Request.GetScopes()); principal.SetScopes(notification.Request.GetScopes());
notification.Principal = principal; notification.Principal = principal;
} }
@ -299,7 +281,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyDeviceResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyDeviceResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -313,14 +295,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -361,14 +337,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -402,7 +372,7 @@ namespace OpenIddict.Server
public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopes([NotNull] IOpenIddictScopeManager scopeManager) public ValidateScopes(IOpenIddictScopeManager scopeManager)
=> _scopeManager = scopeManager; => _scopeManager = scopeManager;
/// <summary> /// <summary>
@ -417,14 +387,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -439,7 +403,11 @@ namespace OpenIddict.Server
{ {
await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray())) await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray()))
{ {
scopes.Remove(await _scopeManager.GetNameAsync(scope)); var name = await _scopeManager.GetNameAsync(scope);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
}
} }
} }
@ -467,7 +435,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -482,20 +450,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
// Retrieve the application details corresponding to the requested client_id. // Retrieve the application details corresponding to the requested client_id.
// If no entity can be found, this likely indicates that the client_id is invalid. // If no entity can be found, this likely indicates that the client_id is invalid.
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
@ -523,7 +487,7 @@ namespace OpenIddict.Server
public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientType([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -538,20 +502,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -599,7 +559,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -614,29 +574,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
} }
// If the application is not a public client, validate the client secret. // If the application is a public client, don't validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) && if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret)) {
return;
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientSecret), SR.FormatID5000(Parameters.ClientSecret));
if (!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7061), context.ClientId); context.Logger.LogError(SR.GetResourceString(SR.ID7061), context.ClientId);
@ -660,7 +622,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -676,20 +638,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -721,7 +679,7 @@ namespace OpenIddict.Server
public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopePermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateScopePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -737,20 +695,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
/// </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] ValidateDeviceRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -788,7 +742,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractVerificationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractVerificationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -802,14 +756,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -856,7 +804,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateVerificationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateVerificationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -870,14 +818,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -919,7 +861,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleVerificationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleVerificationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -933,14 +875,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1014,7 +950,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyVerificationResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyVerificationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -1028,14 +964,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1068,7 +998,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public AttachUserCodePrincipal([NotNull] IOpenIddictServerDispatcher dispatcher) public AttachUserCodePrincipal(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -1081,14 +1011,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(HandleVerificationRequestContext context)
/// </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] HandleVerificationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1109,7 +1033,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // 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. // that want to access the authentication result without triggering a new authentication flow.
context.Transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName, notification); context.Transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {

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

@ -13,7 +13,6 @@ using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
@ -74,7 +73,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractConfigurationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractConfigurationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -88,14 +87,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -142,7 +135,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateConfigurationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateConfigurationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -156,14 +149,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -205,7 +192,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleConfigurationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleConfigurationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -219,14 +206,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -286,7 +267,7 @@ namespace OpenIddict.Server
response.SetParameter(metadata.Key, metadata.Value); response.SetParameter(metadata.Key, metadata.Value);
} }
context.Response = response; context.Transaction.Response = response;
} }
} }
@ -297,7 +278,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyConfigurationResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyConfigurationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -311,14 +292,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -359,14 +334,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -402,7 +371,7 @@ namespace OpenIddict.Server
return default; return default;
static Uri GetEndpointAbsoluteUri(Uri issuer, Uri endpoint) static Uri? GetEndpointAbsoluteUri(Uri? issuer, Uri endpoint)
{ {
// If the endpoint is disabled (i.e a null address is specified), return null. // If the endpoint is disabled (i.e a null address is specified), return null.
if (endpoint == null) if (endpoint == null)
@ -456,14 +425,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -491,14 +454,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -526,14 +483,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -562,14 +513,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -614,14 +559,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -649,14 +588,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -684,14 +617,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -719,14 +646,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -754,14 +675,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -826,14 +741,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleConfigurationRequestContext context)
/// </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] HandleConfigurationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -857,7 +766,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractCryptographyRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractCryptographyRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -871,14 +780,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -925,7 +828,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateCryptographyRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateCryptographyRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -939,14 +842,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -988,7 +885,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleCryptographyRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleCryptographyRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -1002,14 +899,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1111,7 +1002,7 @@ namespace OpenIddict.Server
var response = new OpenIddictResponse(); var response = new OpenIddictResponse();
response.AddParameter(Parameters.Keys, document.RootElement.Clone()); response.AddParameter(Parameters.Keys, document.RootElement.Clone());
context.Response = response; context.Transaction.Response = response;
} }
} }
@ -1122,7 +1013,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyCryptographyResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyCryptographyResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -1136,14 +1027,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -1184,14 +1069,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleCryptographyRequestContext context)
/// </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] HandleCryptographyRequestContext context)
{ {
if (context == null) if (context == null)
{ {

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

@ -10,7 +10,6 @@ using System.Collections.Immutable;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
@ -18,6 +17,7 @@ using static OpenIddict.Abstractions.OpenIddictConstants;
using static OpenIddict.Server.OpenIddictServerEvents; using static OpenIddict.Server.OpenIddictServerEvents;
using static OpenIddict.Server.OpenIddictServerHandlerFilters; using static OpenIddict.Server.OpenIddictServerHandlerFilters;
using SR = OpenIddict.Abstractions.OpenIddictResources; using SR = OpenIddict.Abstractions.OpenIddictResources;
using System.Diagnostics;
#if !SUPPORTS_TIME_CONSTANT_COMPARISONS #if !SUPPORTS_TIME_CONSTANT_COMPARISONS
using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities;
@ -77,7 +77,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractTokenRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractTokenRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -91,14 +91,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -145,7 +139,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateTokenRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateTokenRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -159,14 +153,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -178,7 +166,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the principal without triggering a new validation process. // that want to access the principal without triggering a new validation process.
context.Transaction.SetProperty(typeof(ValidateTokenRequestContext).FullName, notification); context.Transaction.SetProperty(typeof(ValidateTokenRequestContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -212,7 +200,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleTokenRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleTokenRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -226,14 +214,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -307,7 +289,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyTokenResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyTokenResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -321,14 +303,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -369,14 +345,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -437,14 +407,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -492,14 +456,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -539,14 +497,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -585,14 +537,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -630,14 +576,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -677,14 +617,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -719,7 +653,7 @@ namespace OpenIddict.Server
public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopes([NotNull] IOpenIddictScopeManager scopeManager) public ValidateScopes(IOpenIddictScopeManager scopeManager)
=> _scopeManager = scopeManager; => _scopeManager = scopeManager;
/// <summary> /// <summary>
@ -734,14 +668,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -756,7 +684,11 @@ namespace OpenIddict.Server
{ {
await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray())) await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray()))
{ {
scopes.Remove(await _scopeManager.GetNameAsync(scope)); var name = await _scopeManager.GetNameAsync(scope);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
}
} }
} }
@ -784,7 +716,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -799,20 +731,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
// Retrieve the application details corresponding to the requested client_id. // Retrieve the application details corresponding to the requested client_id.
// If no entity can be found, this likely indicates that the client_id is invalid. // If no entity can be found, this likely indicates that the client_id is invalid.
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
@ -840,7 +768,7 @@ namespace OpenIddict.Server
public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientType([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -855,20 +783,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -928,7 +852,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -943,29 +867,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
} }
// If the application is not a public client, validate the client secret. // If the application is a public client, don't validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) && if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret)) {
return;
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientSecret), SR.FormatID5000(Parameters.ClientSecret));
if (!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7085), context.ClientId); context.Logger.LogError(SR.GetResourceString(SR.ID7085), context.ClientId);
@ -989,7 +915,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1005,20 +931,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1050,7 +972,7 @@ namespace OpenIddict.Server
public ValidateGrantTypePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateGrantTypePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateGrantTypePermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateGrantTypePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1066,20 +988,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1125,7 +1043,7 @@ namespace OpenIddict.Server
public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopePermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateScopePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1141,20 +1059,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1196,7 +1110,7 @@ namespace OpenIddict.Server
public ValidateProofKeyForCodeExchangeRequirement() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateProofKeyForCodeExchangeRequirement() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateProofKeyForCodeExchangeRequirement([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateProofKeyForCodeExchangeRequirement(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1211,14 +1125,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1237,6 +1145,8 @@ namespace OpenIddict.Server
return; return;
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -1264,7 +1174,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -1277,14 +1187,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1303,7 +1207,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // 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. // that want to access the authentication result without triggering a new authentication flow.
context.Transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName, notification); context.Transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -1347,14 +1251,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1368,6 +1266,8 @@ namespace OpenIddict.Server
return default; return default;
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
var presenters = context.Principal.GetPresenters(); var presenters = context.Principal.GetPresenters();
if (presenters.IsDefaultOrEmpty) if (presenters.IsDefaultOrEmpty)
{ {
@ -1437,14 +1337,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1456,6 +1350,8 @@ namespace OpenIddict.Server
return default; return default;
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// Validate the redirect_uri sent by the client application as part of this token request. // Validate the redirect_uri sent by the client application as part of this token request.
// Note: for pure OAuth 2.0 requests, redirect_uri is only mandatory if the authorization request // Note: for pure OAuth 2.0 requests, redirect_uri is only mandatory if the authorization request
// contained an explicit redirect_uri. OpenID Connect requests MUST include a redirect_uri // contained an explicit redirect_uri. OpenID Connect requests MUST include a redirect_uri
@ -1510,14 +1406,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateTokenRequestContext context)
/// </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] ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1529,6 +1419,8 @@ namespace OpenIddict.Server
return default; return default;
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// Note: the ValidateProofKeyForCodeExchangeRequirement handler (invoked earlier) ensures // Note: the ValidateProofKeyForCodeExchangeRequirement handler (invoked earlier) ensures
// a code_verifier is specified if the proof key for code exchange requirement was enforced // a code_verifier is specified if the proof key for code exchange requirement was enforced
// for the client application. But unlike the aforementioned handler, ValidateCodeVerifier // for the client application. But unlike the aforementioned handler, ValidateCodeVerifier
@ -1630,23 +1522,26 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context) /// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
if (string.IsNullOrEmpty(context.Request.Scope)) if (!context.Request.IsAuthorizationCodeGrantType() && !context.Request.IsRefreshTokenGrantType())
{ {
return default; return default;
} }
if (!context.Request.IsAuthorizationCodeGrantType() && !context.Request.IsRefreshTokenGrantType()) if (string.IsNullOrEmpty(context.Request.Scope))
{ {
return default; return default;
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// When an explicit scope parameter has been included in the token request // When an explicit scope parameter has been included in the token request
// but was missing from the initial request, the request MUST be rejected. // but was missing from the initial request, the request MUST be rejected.
// See http://tools.ietf.org/html/rfc6749#section-6 for more information. // See http://tools.ietf.org/html/rfc6749#section-6 for more information.
@ -1697,14 +1592,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleTokenRequestContext context)
/// </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] HandleTokenRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -1717,7 +1606,7 @@ namespace OpenIddict.Server
} }
var notification = context.Transaction.GetProperty<ValidateTokenRequestContext>( var notification = context.Transaction.GetProperty<ValidateTokenRequestContext>(
typeof(ValidateTokenRequestContext).FullName) ?? typeof(ValidateTokenRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal; context.Principal ??= notification.Principal;

228
src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs

@ -6,13 +6,13 @@
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@ -70,7 +70,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractIntrospectionRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractIntrospectionRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -84,14 +84,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -138,7 +132,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateIntrospectionRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateIntrospectionRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -152,14 +146,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -171,7 +159,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the principal without triggering a new validation process. // that want to access the principal without triggering a new validation process.
context.Transaction.SetProperty(typeof(ValidateIntrospectionRequestContext).FullName, notification); context.Transaction.SetProperty(typeof(ValidateIntrospectionRequestContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -205,7 +193,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleIntrospectionRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleIntrospectionRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -219,14 +207,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -303,7 +285,7 @@ namespace OpenIddict.Server
response.SetParameter(claim.Key, claim.Value); response.SetParameter(claim.Key, claim.Value);
} }
context.Response = response; context.Transaction.Response = response;
} }
} }
@ -314,7 +296,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyIntrospectionResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyIntrospectionResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -328,14 +310,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -376,14 +352,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -421,14 +391,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -461,7 +425,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -476,20 +440,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
// Retrieve the application details corresponding to the requested client_id. // Retrieve the application details corresponding to the requested client_id.
// If no entity can be found, this likely indicates that the client_id is invalid. // If no entity can be found, this likely indicates that the client_id is invalid.
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
@ -517,7 +477,7 @@ namespace OpenIddict.Server
public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientType([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -532,20 +492,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -593,7 +549,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -608,29 +564,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
} }
// If the application is not a public client, validate the client secret. // If the application is a public client, don't validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) && if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret)) {
return;
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientSecret), SR.FormatID5000(Parameters.ClientSecret));
if (!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7102), context.ClientId); context.Logger.LogError(SR.GetResourceString(SR.ID7102), context.ClientId);
@ -654,7 +612,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -670,20 +628,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -711,7 +665,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -724,14 +678,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -782,20 +730,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) && if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
!context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) && !context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) &&
!context.Principal.HasTokenType(TokenTypeHints.IdToken) && !context.Principal.HasTokenType(TokenTypeHints.IdToken) &&
@ -834,20 +778,17 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
/// </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] ValidateIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// When the introspected token is an authorization code, the caller must be // When the introspected token is an authorization code, the caller must be
// listed as a presenter (i.e the party the authorization code was issued to). // listed as a presenter (i.e the party the authorization code was issued to).
if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode)) if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode))
@ -940,14 +881,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleIntrospectionRequestContext context)
/// </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] HandleIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -955,7 +890,7 @@ namespace OpenIddict.Server
} }
var notification = context.Transaction.GetProperty<ValidateIntrospectionRequestContext>( var notification = context.Transaction.GetProperty<ValidateIntrospectionRequestContext>(
typeof(ValidateIntrospectionRequestContext).FullName) ?? typeof(ValidateIntrospectionRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal; context.Principal ??= notification.Principal;
@ -979,20 +914,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleIntrospectionRequestContext context)
/// </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] HandleIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
context.TokenId = context.Principal.GetClaim(Claims.JwtId); context.TokenId = context.Principal.GetClaim(Claims.JwtId);
context.TokenUsage = context.Principal.GetTokenType(); context.TokenUsage = context.Principal.GetTokenType();
context.Subject = context.Principal.GetClaim(Claims.Subject); context.Subject = context.Principal.GetClaim(Claims.Subject);
@ -1028,7 +959,7 @@ namespace OpenIddict.Server
public AttachApplicationClaims() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public AttachApplicationClaims() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public AttachApplicationClaims([NotNull] IOpenIddictApplicationManager applicationManager) public AttachApplicationClaims(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -1043,20 +974,17 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(HandleIntrospectionRequestContext context)
/// </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] HandleIntrospectionRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), SR.FormatID5000(Parameters.ClientId));
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// Don't return application-specific claims if the token is not an access or identity token. // Don't return application-specific claims if the token is not an access or identity token.
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) && !context.Principal.HasTokenType(TokenTypeHints.IdToken)) if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) && !context.Principal.HasTokenType(TokenTypeHints.IdToken))
{ {
@ -1166,14 +1094,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyIntrospectionResponseContext context)
/// </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] ApplyIntrospectionResponseContext context)
{ {
if (context == null) if (context == null)
{ {

215
src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs

@ -6,8 +6,8 @@
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
@ -62,7 +62,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractRevocationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractRevocationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -76,14 +76,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -130,7 +124,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateRevocationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateRevocationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -144,14 +138,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -163,7 +151,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the principal without triggering a new validation process. // that want to access the principal without triggering a new validation process.
context.Transaction.SetProperty(typeof(ValidateRevocationRequestContext).FullName, notification); context.Transaction.SetProperty(typeof(ValidateRevocationRequestContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -197,7 +185,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleRevocationRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleRevocationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -211,14 +199,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -249,7 +231,7 @@ namespace OpenIddict.Server
return; return;
} }
context.Response = new OpenIddictResponse(); context.Transaction.Response = new OpenIddictResponse();
} }
} }
@ -260,7 +242,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyRevocationResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyRevocationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -274,14 +256,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -322,14 +298,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -367,14 +337,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -407,7 +371,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -422,20 +386,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
// Retrieve the application details corresponding to the requested client_id. // Retrieve the application details corresponding to the requested client_id.
// If no entity can be found, this likely indicates that the client_id is invalid. // If no entity can be found, this likely indicates that the client_id is invalid.
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
@ -463,7 +423,7 @@ namespace OpenIddict.Server
public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientType([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -478,20 +438,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -539,7 +495,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -554,29 +510,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
} }
// If the application is not a public client, validate the client secret. // If the application is a public client, don't validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) && if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret)) {
return;
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientSecret), SR.FormatID5000(Parameters.ClientSecret));
if (!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7115), context.ClientId); context.Logger.LogError(SR.GetResourceString(SR.ID7115), context.ClientId);
@ -600,7 +558,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -616,20 +574,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId); var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null) if (application == null)
{ {
@ -657,7 +611,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -670,14 +624,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -728,20 +676,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) && if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
!context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) && !context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) &&
!context.Principal.HasTokenType(TokenTypeHints.RefreshToken)) !context.Principal.HasTokenType(TokenTypeHints.RefreshToken))
@ -779,20 +723,17 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateRevocationRequestContext context)
/// </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] ValidateRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// When the revoked token is an authorization code, the caller must be // When the revoked token is an authorization code, the caller must be
// listed as a presenter (i.e the party the authorization code was issued to). // listed as a presenter (i.e the party the authorization code was issued to).
if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode)) if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode))
@ -885,14 +826,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleRevocationRequestContext context)
/// </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] HandleRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -900,7 +835,7 @@ namespace OpenIddict.Server
} }
var notification = context.Transaction.GetProperty<ValidateRevocationRequestContext>( var notification = context.Transaction.GetProperty<ValidateRevocationRequestContext>(
typeof(ValidateRevocationRequestContext).FullName) ?? typeof(ValidateRevocationRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal; context.Principal ??= notification.Principal;
@ -919,7 +854,7 @@ namespace OpenIddict.Server
public RevokeToken() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public RevokeToken() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public RevokeToken([NotNull] IOpenIddictTokenManager tokenManager) public RevokeToken(IOpenIddictTokenManager tokenManager)
=> _tokenManager = tokenManager; => _tokenManager = tokenManager;
/// <summary> /// <summary>
@ -933,20 +868,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(HandleRevocationRequestContext context)
/// </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] HandleRevocationRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// Extract the token identifier from the authentication principal. // Extract the token identifier from the authentication principal.
var identifier = context.Principal.GetTokenId(); var identifier = context.Principal.GetTokenId();
if (string.IsNullOrEmpty(identifier)) if (string.IsNullOrEmpty(identifier))
@ -999,14 +930,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyRevocationResponseContext context)
/// </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] ApplyRevocationResponseContext context)
{ {
if (context == null) if (context == null)
{ {

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

@ -6,8 +6,8 @@
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
@ -51,7 +51,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractLogoutRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractLogoutRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -65,14 +65,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -119,7 +113,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateLogoutRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateLogoutRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -133,14 +127,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -152,7 +140,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the redirect_uri without triggering a new validation process. // that want to access the redirect_uri without triggering a new validation process.
context.Transaction.SetProperty(typeof(ValidateLogoutRequestContext).FullName, notification); context.Transaction.SetProperty(typeof(ValidateLogoutRequestContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -186,7 +174,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleLogoutRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleLogoutRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -200,14 +188,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -280,7 +262,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyLogoutResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyLogoutResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -294,14 +276,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -342,14 +318,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateLogoutRequestContext context)
/// </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] ValidateLogoutRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -362,7 +332,7 @@ namespace OpenIddict.Server
} }
// If an optional post_logout_redirect_uri was provided, validate it. // If an optional post_logout_redirect_uri was provided, validate it.
if (!Uri.TryCreate(context.PostLogoutRedirectUri, UriKind.Absolute, out Uri uri) || !uri.IsWellFormedOriginalString()) if (!Uri.TryCreate(context.PostLogoutRedirectUri, UriKind.Absolute, out Uri? uri) || !uri.IsWellFormedOriginalString())
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7126), Parameters.PostLogoutRedirectUri, context.PostLogoutRedirectUri); context.Logger.LogError(SR.GetResourceString(SR.ID7126), Parameters.PostLogoutRedirectUri, context.PostLogoutRedirectUri);
@ -398,7 +368,7 @@ namespace OpenIddict.Server
public ValidateClientPostLogoutRedirectUri() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015)); public ValidateClientPostLogoutRedirectUri() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientPostLogoutRedirectUri([NotNull] IOpenIddictApplicationManager applicationManager) public ValidateClientPostLogoutRedirectUri(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager; => _applicationManager = applicationManager;
/// <summary> /// <summary>
@ -413,20 +383,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateLogoutRequestContext context)
/// </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] ValidateLogoutRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(!string.IsNullOrEmpty(context.PostLogoutRedirectUri), SR.FormatID5000(Parameters.PostLogoutRedirectUri));
if (!await ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri)) if (!await ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri))
{ {
context.Logger.LogError(SR.GetResourceString(SR.ID7128), context.PostLogoutRedirectUri); context.Logger.LogError(SR.GetResourceString(SR.ID7128), context.PostLogoutRedirectUri);
@ -473,14 +439,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyLogoutResponseContext context)
/// </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] ApplyLogoutResponseContext context)
{ {
if (context == null) if (context == null)
{ {
@ -493,7 +453,7 @@ namespace OpenIddict.Server
} }
var notification = context.Transaction.GetProperty<ValidateLogoutRequestContext>( var notification = context.Transaction.GetProperty<ValidateLogoutRequestContext>(
typeof(ValidateLogoutRequestContext).FullName); typeof(ValidateLogoutRequestContext).FullName!);
// Note: at this stage, the validated redirect URI property may be null (e.g if // Note: at this stage, the validated redirect URI property may be null (e.g if
// an error is returned from the ExtractLogoutRequest/ValidateLogoutRequest events). // an error is returned from the ExtractLogoutRequest/ValidateLogoutRequest events).
@ -521,14 +481,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ApplyLogoutResponseContext context)
/// </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] ApplyLogoutResponseContext context)
{ {
if (context == null) if (context == null)
{ {

112
src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs

@ -6,9 +6,9 @@
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Abstractions.OpenIddictConstants;
@ -53,7 +53,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractUserinfoRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ExtractUserinfoRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -67,14 +67,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -121,7 +115,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateUserinfoRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateUserinfoRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -135,14 +129,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -154,7 +142,7 @@ namespace OpenIddict.Server
// Store the context object in the transaction so it can be later retrieved by handlers // Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the principal without triggering a new validation process. // that want to access the principal without triggering a new validation process.
context.Transaction.SetProperty(typeof(ValidateUserinfoRequestContext).FullName, notification); context.Transaction.SetProperty(typeof(ValidateUserinfoRequestContext).FullName!, notification);
if (notification.IsRequestHandled) if (notification.IsRequestHandled)
{ {
@ -188,7 +176,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleUserinfoRequest([NotNull] IOpenIddictServerDispatcher dispatcher) public HandleUserinfoRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -202,14 +190,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ProcessRequestContext context)
/// </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] ProcessRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -275,7 +257,7 @@ namespace OpenIddict.Server
response.SetParameter(claim.Key, claim.Value); response.SetParameter(claim.Key, claim.Value);
} }
context.Response = response; context.Transaction.Response = response;
} }
} }
@ -286,7 +268,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyUserinfoResponse([NotNull] IOpenIddictServerDispatcher dispatcher) public ApplyUserinfoResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -300,14 +282,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(TContext context)
/// </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)
{ {
if (context == null) if (context == null)
{ {
@ -348,14 +324,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(ValidateUserinfoRequestContext context)
/// </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] ValidateUserinfoRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -384,7 +354,7 @@ namespace OpenIddict.Server
{ {
private readonly IOpenIddictServerDispatcher _dispatcher; private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher) public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher; => _dispatcher = dispatcher;
/// <summary> /// <summary>
@ -397,14 +367,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public async ValueTask HandleAsync(ValidateUserinfoRequestContext context)
/// </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] ValidateUserinfoRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -456,14 +420,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleUserinfoRequestContext context)
/// </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] HandleUserinfoRequestContext context)
{ {
if (context == null) if (context == null)
{ {
@ -471,7 +429,7 @@ namespace OpenIddict.Server
} }
var notification = context.Transaction.GetProperty<ValidateUserinfoRequestContext>( var notification = context.Transaction.GetProperty<ValidateUserinfoRequestContext>(
typeof(ValidateUserinfoRequestContext).FullName) ?? typeof(ValidateUserinfoRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal; context.Principal ??= notification.Principal;
@ -495,20 +453,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleUserinfoRequestContext context)
/// </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] HandleUserinfoRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// Note: when receiving an access token, its audiences list cannot be used for the "aud" claim // Note: when receiving an access token, its audiences list cannot be used for the "aud" claim
// as the client application is not the intented audience but only an authorized presenter. // as the client application is not the intented audience but only an authorized presenter.
// See http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse // See http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
@ -533,20 +487,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn) .SetType(OpenIddictServerHandlerType.BuiltIn)
.Build(); .Build();
/// <summary> /// <inheritdoc/>
/// Processes the event. public ValueTask HandleAsync(HandleUserinfoRequestContext context)
/// </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] HandleUserinfoRequestContext context)
{ {
if (context == null) if (context == null)
{ {
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
context.Subject = context.Principal.GetClaim(Claims.Subject); context.Subject = context.Principal.GetClaim(Claims.Subject);
// The following claims are all optional and should be excluded when // The following claims are all optional and should be excluded when

723
src/OpenIddict.Server/OpenIddictServerHandlers.cs

File diff suppressed because it is too large

9
src/OpenIddict.Server/OpenIddictServerHelpers.cs

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

2
src/OpenIddict.Server/OpenIddictServerOptions.cs

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

16
src/OpenIddict.Server/OpenIddictServerTransaction.cs

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

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

@ -1722,17 +1722,7 @@ namespace OpenIddict.Server.Tests
private class CustomHandler : IOpenIddictServerHandler<CustomContext> private class CustomHandler : IOpenIddictServerHandler<CustomContext>
{ {
/// <summary> public ValueTask HandleAsync(CustomContext context) => default;
/// 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(CustomContext context)
{
return new ValueTask();
}
} }
} }
} }
Loading…
Cancel
Save