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
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETFramework') Or
('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.0')) And
$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0'))) Or
('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.0')) And
$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '2.1'))) ">
('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '2.1'))) Or
('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '2.0'))) ">
<PackageVersion Include="Microsoft.AspNetCore.Authentication" Version="2.1.2" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="2.1.2" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection" Version="2.1.1" />
@ -51,9 +49,8 @@
</ItemGroup>
<ItemGroup
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.0')) And
$([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '5.0'))) Or
('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '2.1'))) ">
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '3.1'))) Or
('$(TargetFrameworkIdentifier)' == '.NETStandard' And $([MSBuild]::VersionEquals($(TargetFrameworkVersion), '2.1'))) ">
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.6" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection" 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>
<TargetFrameworks>net461;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
@ -14,12 +15,12 @@
</ItemGroup>
<ItemGroup
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.1')) ">
Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.0')) ">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup
Condition=" '$(TargetFrameworkIdentifier)' != '.NETCoreApp' Or $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.1')) ">
Condition=" '$(TargetFrameworkIdentifier)' != '.NETCoreApp' Or $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0')) ">
<PackageReference Include="Microsoft.AspNetCore.Authentication" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" />

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

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

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

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

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

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
@ -28,7 +27,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerAspNetCoreBuilder"/>.</returns>
public static OpenIddictServerAspNetCoreBuilder UseAspNetCore([NotNull] this OpenIddictServerBuilder builder)
public static OpenIddictServerAspNetCoreBuilder UseAspNetCore(this OpenIddictServerBuilder builder)
{
if (builder == null)
{
@ -79,8 +78,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public static OpenIddictServerBuilder UseAspNetCore(
[NotNull] this OpenIddictServerBuilder builder,
[NotNull] Action<OpenIddictServerAspNetCoreBuilder> configuration)
this OpenIddictServerBuilder builder, Action<OpenIddictServerAspNetCoreBuilder> configuration)
{
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
/// information about an individual OpenID Connect server request.
/// </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.Collections.Generic;
using System.Diagnostics;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@ -36,18 +36,19 @@ namespace OpenIddict.Server.AspNetCore
/// Creates a new instance of the <see cref="OpenIddictServerAspNetCoreHandler"/> class.
/// </summary>
public OpenIddictServerAspNetCoreHandler(
[NotNull] IOpenIddictServerDispatcher dispatcher,
[NotNull] IOpenIddictServerFactory factory,
[NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options,
[NotNull] ILoggerFactory logger,
[NotNull] UrlEncoder encoder,
[NotNull] ISystemClock clock)
IOpenIddictServerDispatcher dispatcher,
IOpenIddictServerFactory factory,
IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock)
: base(options, logger, encoder, clock)
{
_dispatcher = dispatcher;
_factory = factory;
}
/// <inheritdoc/>
public async Task<bool> HandleRequestAsync()
{
// Note: the transaction may be already attached when replaying an ASP.NET Core request
@ -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.
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
// so that it can retrieved while performing sign-in/sign-out operations.
@ -107,6 +108,7 @@ namespace OpenIddict.Server.AspNetCore
return false;
}
/// <inheritdoc/>
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
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
// (generally later in the pipeline, when using the pass-through mode). To avoid having to re-validate it,
// the authentication context is resolved from the transaction. If it's not available, a new one is created.
var context = transaction.GetProperty<ProcessAuthenticationContext>(typeof(ProcessAuthenticationContext).FullName);
var context = transaction.GetProperty<ProcessAuthenticationContext>(typeof(ProcessAuthenticationContext).FullName!);
if (context == null)
{
context = new ProcessAuthenticationContext(transaction);
@ -123,7 +125,7 @@ namespace OpenIddict.Server.AspNetCore
// Store the context object in the transaction so it can be later retrieved by handlers
// that want to access the authentication result without triggering a new authentication flow.
transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName, context);
transaction.SetProperty(typeof(ProcessAuthenticationContext).FullName!, context);
}
if (context.IsRequestHandled || context.IsRequestSkipped)
@ -141,7 +143,7 @@ namespace OpenIddict.Server.AspNetCore
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.ErrorDescription] = context.ErrorDescription,
@ -153,14 +155,18 @@ namespace OpenIddict.Server.AspNetCore
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).
var properties = new AuthenticationProperties();
properties.StoreTokens(new[]
{
new AuthenticationToken
{
Name = context.TokenType,
Name = context.Principal.GetTokenType(),
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 ??
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)
{
@ -213,10 +220,12 @@ namespace OpenIddict.Server.AspNetCore
}
}
protected override Task HandleForbiddenAsync([CanBeNull] AuthenticationProperties properties)
/// <inheritdoc/>
protected override Task HandleForbiddenAsync(AuthenticationProperties? 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)
{
@ -226,7 +235,7 @@ namespace OpenIddict.Server.AspNetCore
var transaction = Context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction ??
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)
{
@ -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 ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1111));
@ -274,7 +284,7 @@ namespace OpenIddict.Server.AspNetCore
Response = new OpenIddictResponse()
};
transaction.Properties[typeof(AuthenticationProperties).FullName] = properties ?? new AuthenticationProperties();
transaction.Properties[typeof(AuthenticationProperties).FullName!] = properties ?? new AuthenticationProperties();
await _dispatcher.DispatchAsync(context);

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

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

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

@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Claims;
@ -15,7 +16,6 @@ using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed;
@ -72,7 +72,7 @@ namespace OpenIddict.Server.AspNetCore
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache)
public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -87,20 +87,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
{
if (context == null)
{
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,
// 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(
[NotNull] IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
IDistributedCache cache,
IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
{
_cache = cache;
_options = options;
@ -192,20 +188,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
{
if (context == null)
{
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 may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetHttpRequest();
@ -285,7 +277,7 @@ namespace OpenIddict.Server.AspNetCore
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache)
public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -300,14 +292,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
if (context == null)
{
@ -337,7 +323,7 @@ namespace OpenIddict.Server.AspNetCore
{
private readonly HtmlEncoder _encoder;
public ProcessFormPostResponse([NotNull] HtmlEncoder encoder)
public ProcessFormPostResponse(HtmlEncoder encoder)
=> _encoder = encoder;
/// <summary>
@ -351,14 +337,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: 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)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value))
{
location = QueryHelpers.AddQueryString(location, key, value);
@ -515,14 +491,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value))
{
builder.Append(Contains(builder, '#') ? '&' : '#')

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

@ -7,12 +7,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed;
@ -69,7 +69,7 @@ namespace OpenIddict.Server.AspNetCore
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache)
public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -84,20 +84,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractLogoutRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
{
if (context == null)
{
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,
// 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(
[NotNull] IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
IDistributedCache cache,
IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
{
_cache = cache;
_options = options;
@ -189,20 +185,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractLogoutRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
{
if (context == null)
{
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 may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetHttpRequest();
@ -282,7 +274,7 @@ namespace OpenIddict.Server.AspNetCore
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache)
public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -297,14 +289,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyLogoutResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyLogoutResponseContext context)
{
if (context == null)
{
@ -343,14 +329,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyLogoutResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyLogoutResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: 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.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Diagnostics;
@ -84,14 +84,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -192,14 +186,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -230,7 +218,7 @@ namespace OpenIddict.Server.AspNetCore
return default;
}
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer) ||
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) ||
!issuer.IsWellFormedOriginalString())
{
context.Reject(
@ -264,14 +252,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -323,21 +305,15 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessChallengeContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName);
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties != null)
{
context.Response.Error = properties.GetString(Properties.Error);
@ -367,21 +343,17 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
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)
{
return default;
@ -390,7 +362,7 @@ namespace OpenIddict.Server.AspNetCore
foreach (var parameter in properties.Parameters)
{
// 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,
JsonElement value => value,
@ -425,14 +397,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -449,7 +415,7 @@ namespace OpenIddict.Server.AspNetCore
if (HttpMethods.IsGet(request.Method))
{
context.Request = new OpenIddictRequest(request.Query);
context.Transaction.Request = new OpenIddictRequest(request.Query);
}
else
@ -484,14 +450,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -508,7 +468,7 @@ namespace OpenIddict.Server.AspNetCore
if (HttpMethods.IsGet(request.Method))
{
context.Request = new OpenIddictRequest(request.Query);
context.Transaction.Request = new OpenIddictRequest(request.Query);
}
else if (HttpMethods.IsPost(request.Method))
@ -537,7 +497,7 @@ namespace OpenIddict.Server.AspNetCore
return;
}
context.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted));
context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted));
}
else
@ -570,14 +530,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -618,7 +572,7 @@ namespace OpenIddict.Server.AspNetCore
return;
}
context.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted));
context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync(request.HttpContext.RequestAborted));
}
else
@ -652,20 +606,16 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetHttpRequest();
@ -682,7 +632,8 @@ namespace OpenIddict.Server.AspNetCore
// At this point, reject requests that use multiple client authentication methods.
// 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));
@ -709,8 +660,8 @@ namespace OpenIddict.Server.AspNetCore
}
// Attach the basic authentication credentials to the request message.
context.Request.ClientId = UnescapeDataString(data.Substring(0, index));
context.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1));
context.Transaction.Request.ClientId = UnescapeDataString(data.Substring(0, index));
context.Transaction.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1));
return default;
}
@ -724,7 +675,7 @@ namespace OpenIddict.Server.AspNetCore
return default;
}
static string UnescapeDataString(string data)
static string? UnescapeDataString(string data)
{
if (string.IsNullOrEmpty(data))
{
@ -754,14 +705,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -776,6 +721,8 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
}
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
string header = request.Headers[HeaderNames.Authorization];
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.
context.Request.AccessToken = header.Substring("Bearer ".Length);
context.Transaction.Request.AccessToken = header.Substring("Bearer ".Length);
return default;
}
@ -809,14 +756,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -846,14 +787,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -868,6 +803,8 @@ namespace OpenIddict.Server.AspNetCore
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
// 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
@ -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
// 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.
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).
@ -910,14 +847,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -949,7 +880,7 @@ namespace OpenIddict.Server.AspNetCore
{
private readonly IOptionsMonitor<OpenIddictServerAspNetCoreOptions> _options;
public AttachWwwAuthenticateHeader([NotNull] IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
public AttachWwwAuthenticateHeader(IOptionsMonitor<OpenIddictServerAspNetCoreOptions> options)
=> _options = options;
/// <summary>
@ -963,14 +894,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -985,6 +910,8 @@ namespace OpenIddict.Server.AspNetCore
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
// 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
@ -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
// 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.
var scheme = context.Response.Error switch
var scheme = context.Transaction.Response.Error switch
{
Errors.InvalidClient => Schemes.Basic,
@ -1017,11 +944,11 @@ namespace OpenIddict.Server.AspNetCore
parameters[Parameters.Realm] = _options.CurrentValue.Realm;
}
foreach (var parameter in context.Response.GetParameters())
foreach (var parameter in context.Transaction.Response.GetParameters())
{
// Note: the error details are only included if the error was not caused by a missing token, as recommended
// by the OAuth 2.0 bearer specification: https://tools.ietf.org/html/rfc6750#section-3.1.
if (string.Equals(context.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
if (string.Equals(context.Transaction.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
(string.Equals(parameter.Key, Parameters.Error, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal)))
@ -1030,7 +957,7 @@ namespace OpenIddict.Server.AspNetCore
}
// Ignore values that can't be represented as unique strings.
var value = (string) parameter.Value;
var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value))
{
continue;
@ -1081,14 +1008,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1109,7 +1030,7 @@ namespace OpenIddict.Server.AspNetCore
return default;
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Transaction.Response);
context.HandleRequest();
return default;
@ -1133,14 +1054,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1155,10 +1070,10 @@ namespace OpenIddict.Server.AspNetCore
throw new InvalidOperationException(SR.GetResourceString(SR.ID1113));
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Response, new JsonSerializerOptions
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
@ -1196,14 +1111,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1218,7 +1127,9 @@ namespace OpenIddict.Server.AspNetCore
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;
}
@ -1248,14 +1159,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1270,7 +1175,9 @@ namespace OpenIddict.Server.AspNetCore
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;
}
@ -1311,14 +1218,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1333,24 +1234,26 @@ namespace OpenIddict.Server.AspNetCore
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;
}
// 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 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
// objects that can't be represented as strings.
var value = (string) parameter.Value;
var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value))
{
continue;
@ -1392,14 +1295,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1414,7 +1311,7 @@ namespace OpenIddict.Server.AspNetCore
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))
{
response.Redirect(properties.RedirectUri);
@ -1445,14 +1342,8 @@ namespace OpenIddict.Server.AspNetCore
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{

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

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

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

@ -97,10 +97,9 @@ namespace OpenIddict.Server.AspNetCore
public bool EnableStatusCodePagesIntegration { get; set; }
/// <summary>
/// Gets or sets the optional "realm" value returned to
/// the caller as part of the WWW-Authenticate header.
/// Gets or sets the optional "realm" value returned to the caller as part of the WWW-Authenticate header.
/// </summary>
public string Realm { get; set; }
public string? Realm { get; set; }
/// <summary>
/// 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.Security.Claims;
using JetBrains.Annotations;
namespace OpenIddict.Server.DataProtection
{
public interface IOpenIddictServerDataProtectionFormatter
{
ClaimsPrincipal ReadToken([NotNull] BinaryReader reader);
void WriteToken([NotNull] BinaryWriter writer, [NotNull] ClaimsPrincipal principal);
ClaimsPrincipal? ReadToken(BinaryReader reader);
void WriteToken(BinaryWriter writer, ClaimsPrincipal principal);
}
}

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

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

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

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

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

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

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

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
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>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public static OpenIddictServerDataProtectionBuilder UseDataProtection([NotNull] this OpenIddictServerBuilder builder)
public static OpenIddictServerDataProtectionBuilder UseDataProtection(this OpenIddictServerBuilder builder)
{
if (builder == null)
{
@ -67,8 +66,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public static OpenIddictServerBuilder UseDataProtection(
[NotNull] this OpenIddictServerBuilder builder,
[NotNull] Action<OpenIddictServerDataProtectionBuilder> configuration)
this OpenIddictServerBuilder builder, Action<OpenIddictServerDataProtectionBuilder> configuration)
{
if (builder == null)
{

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

@ -12,7 +12,6 @@ using System.Linq;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Text.Json;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
using Properties = OpenIddict.Server.DataProtection.OpenIddictServerDataProtectionConstants.Properties;
@ -21,7 +20,7 @@ namespace OpenIddict.Server.DataProtection
{
public class OpenIddictServerDataProtectionFormatter : IOpenIddictServerDataProtectionFormatter
{
public ClaimsPrincipal ReadToken([NotNull] BinaryReader reader)
public ClaimsPrincipal? ReadToken(BinaryReader reader)
{
if (reader == null)
{
@ -60,7 +59,7 @@ namespace OpenIddict.Server.DataProtection
.SetClaim(Claims.Private.TokenId, GetProperty(properties, Properties.InternalTokenId))
.SetClaim(Claims.Private.UserCodeLifetime, GetProperty(properties, Properties.UserCodeLifetime));
static (ClaimsPrincipal principal, IReadOnlyDictionary<string, string> properties) Read(BinaryReader reader)
static (ClaimsPrincipal? principal, IReadOnlyDictionary<string, string> properties) Read(BinaryReader reader)
{
// Read the version of the format used to serialize the ticket.
var version = reader.ReadInt32();
@ -177,7 +176,7 @@ namespace OpenIddict.Server.DataProtection
return value;
}
static string GetProperty(IReadOnlyDictionary<string, string> properties, string name)
static string? GetProperty(IReadOnlyDictionary<string, string> properties, string name)
=> properties.TryGetValue(name, out var value) ? value : null;
static ImmutableArray<string> GetArrayProperty(IReadOnlyDictionary<string, string> properties, string name)
@ -185,7 +184,7 @@ namespace OpenIddict.Server.DataProtection
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)
{
@ -261,7 +260,7 @@ namespace OpenIddict.Server.DataProtection
// 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).
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.
writer.Write(/* version: */ 5);
@ -360,7 +359,7 @@ namespace OpenIddict.Server.DataProtection
static void WriteWithDefault(BinaryWriter writer, string value, string defaultValue)
=> 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))
{

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

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

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

@ -10,7 +10,6 @@ using System.ComponentModel;
using System.IO;
using System.Security.Claims;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -53,7 +52,7 @@ namespace OpenIddict.Server.DataProtection
{
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public ValidateDataProtectionToken([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
public ValidateDataProtectionToken(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -66,14 +65,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessAuthenticationContext context)
{
if (context == null)
{
@ -120,7 +113,7 @@ namespace OpenIddict.Server.DataProtection
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.
var protector = _options.CurrentValue.DataProtectionProvider.CreateProtector(type switch
@ -176,7 +169,7 @@ namespace OpenIddict.Server.DataProtection
{
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionAccessToken([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
public GenerateDataProtectionAccessToken(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -191,14 +184,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessSignInContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessSignInContext context)
{
if (context == null)
{
@ -211,6 +198,11 @@ namespace OpenIddict.Server.DataProtection
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.
var protector = context.Options.UseReferenceAccessTokens ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -240,7 +232,7 @@ namespace OpenIddict.Server.DataProtection
{
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionAuthorizationCode([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
public GenerateDataProtectionAuthorizationCode(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -255,14 +247,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessSignInContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessSignInContext context)
{
if (context == null)
{
@ -275,6 +261,11 @@ namespace OpenIddict.Server.DataProtection
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.
var protector = !context.Options.DisableTokenStorage ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -304,7 +295,7 @@ namespace OpenIddict.Server.DataProtection
{
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionDeviceCode([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
public GenerateDataProtectionDeviceCode(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -319,14 +310,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessSignInContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessSignInContext context)
{
if (context == null)
{
@ -339,6 +324,11 @@ namespace OpenIddict.Server.DataProtection
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.
var protector = !context.Options.DisableTokenStorage ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -368,7 +358,7 @@ namespace OpenIddict.Server.DataProtection
{
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionRefreshToken([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
public GenerateDataProtectionRefreshToken(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -383,14 +373,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessSignInContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessSignInContext context)
{
if (context == null)
{
@ -403,6 +387,11 @@ namespace OpenIddict.Server.DataProtection
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.
var protector = context.Options.UseReferenceRefreshTokens ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@ -432,7 +421,7 @@ namespace OpenIddict.Server.DataProtection
{
private readonly IOptionsMonitor<OpenIddictServerDataProtectionOptions> _options;
public GenerateDataProtectionUserCode([NotNull] IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
public GenerateDataProtectionUserCode(IOptionsMonitor<OpenIddictServerDataProtectionOptions> options)
=> _options = options;
/// <summary>
@ -447,14 +436,8 @@ namespace OpenIddict.Server.DataProtection
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessSignInContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessSignInContext context)
{
if (context == null)
{
@ -467,6 +450,11 @@ namespace OpenIddict.Server.DataProtection
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.
var protector = !context.Options.DisableTokenStorage ?
_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
/// is directly retrieved from the dependency injection container.
/// </summary>
public IDataProtectionProvider DataProtectionProvider { get; set; }
public IDataProtectionProvider DataProtectionProvider { get; set; } = default!;
/// <summary>
/// Gets or sets the formatter used to read and write Data Protection tokens.

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

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

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

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

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

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

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

@ -6,7 +6,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
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>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerOwinBuilder"/>.</returns>
public static OpenIddictServerOwinBuilder UseOwin([NotNull] this OpenIddictServerBuilder builder)
public static OpenIddictServerOwinBuilder UseOwin(this OpenIddictServerBuilder builder)
{
if (builder == null)
{
@ -76,8 +75,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public static OpenIddictServerBuilder UseOwin(
[NotNull] this OpenIddictServerBuilder builder,
[NotNull] Action<OpenIddictServerOwinBuilder> configuration)
this OpenIddictServerBuilder builder, Action<OpenIddictServerOwinBuilder> configuration)
{
if (builder == null)
{

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

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

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

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

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

@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Claims;
@ -15,7 +16,6 @@ using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -71,7 +71,7 @@ namespace OpenIddict.Server.Owin
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache)
public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -86,20 +86,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
{
if (context == null)
{
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,
// 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(
[NotNull] IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
IDistributedCache cache,
IOptionsMonitor<OpenIddictServerOwinOptions> options)
{
_cache = cache;
_options = options;
@ -191,20 +187,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractAuthorizationRequestContext context)
{
if (context == null)
{
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 may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest();
@ -279,7 +271,7 @@ namespace OpenIddict.Server.Owin
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache)
public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -294,14 +286,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
if (context == null)
{
@ -331,7 +317,7 @@ namespace OpenIddict.Server.Owin
{
private readonly HtmlEncoder _encoder;
public ProcessFormPostResponse([NotNull] HtmlEncoder encoder)
public ProcessFormPostResponse(HtmlEncoder encoder)
=> _encoder = encoder;
/// <summary>
@ -345,14 +331,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: 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)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value))
{
location = WebUtilities.AddQueryString(location, key, value);
@ -510,14 +486,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: value))
{
builder.Append(Contains(builder, '#') ? '&' : '#')

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

@ -7,12 +7,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -68,7 +68,7 @@ namespace OpenIddict.Server.Owin
public RestoreCachedRequestParameters() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RestoreCachedRequestParameters([NotNull] IDistributedCache cache)
public RestoreCachedRequestParameters(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -83,20 +83,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractLogoutRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
{
if (context == null)
{
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,
// 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(
[NotNull] IDistributedCache cache,
[NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
IDistributedCache cache,
IOptionsMonitor<OpenIddictServerOwinOptions> options)
{
_cache = cache;
_options = options;
@ -188,20 +184,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ExtractLogoutRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ExtractLogoutRequestContext context)
{
if (context == null)
{
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 may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest();
@ -276,7 +268,7 @@ namespace OpenIddict.Server.Owin
public RemoveCachedRequest() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1115));
public RemoveCachedRequest([NotNull] IDistributedCache cache)
public RemoveCachedRequest(IDistributedCache cache)
=> _cache = cache;
/// <summary>
@ -291,14 +283,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyLogoutResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyLogoutResponseContext context)
{
if (context == null)
{
@ -337,14 +323,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyLogoutResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyLogoutResponseContext context)
{
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.
foreach (var (key, value) in
from parameter in context.Response.GetParameters()
let values = (string[]) parameter.Value
let values = (string?[]?) parameter.Value
where values != null
from value in values
where !string.IsNullOrEmpty(value)
select (parameter.Key, Value: 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.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Owin;
@ -72,14 +72,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -180,14 +174,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -218,7 +206,7 @@ namespace OpenIddict.Server.Owin
return default;
}
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri issuer) ||
if (!Uri.TryCreate(request.Scheme + "://" + request.Host + request.PathBase, UriKind.Absolute, out Uri? issuer) ||
!issuer.IsWellFormedOriginalString())
{
context.Reject(
@ -252,14 +240,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -311,21 +293,15 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ProcessChallengeContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ProcessChallengeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName);
var properties = context.Transaction.GetProperty<AuthenticationProperties>(typeof(AuthenticationProperties).FullName!);
if (properties != null)
{
context.Response.Error = GetProperty(properties, Properties.Error);
@ -336,8 +312,8 @@ namespace OpenIddict.Server.Owin
return default;
static string GetProperty(AuthenticationProperties properties, string name)
=> properties.Dictionary.TryGetValue(name, out string value) ? value : null;
static string? GetProperty(AuthenticationProperties properties, string name)
=> properties.Dictionary.TryGetValue(name, out string? value) ? value : null;
}
}
@ -358,14 +334,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -382,7 +352,7 @@ namespace OpenIddict.Server.Owin
if (string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase))
{
context.Request = new OpenIddictRequest(request.Query);
context.Transaction.Request = new OpenIddictRequest(request.Query);
}
else
@ -417,14 +387,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -441,7 +405,7 @@ namespace OpenIddict.Server.Owin
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))
@ -470,7 +434,7 @@ namespace OpenIddict.Server.Owin
return;
}
context.Request = new OpenIddictRequest(await request.ReadFormAsync());
context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync());
}
else
@ -503,14 +467,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -551,7 +509,7 @@ namespace OpenIddict.Server.Owin
return;
}
context.Request = new OpenIddictRequest(await request.ReadFormAsync());
context.Transaction.Request = new OpenIddictRequest(await request.ReadFormAsync());
}
else
@ -585,20 +543,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest();
@ -615,7 +569,8 @@ namespace OpenIddict.Server.Owin
// At this point, reject requests that use multiple client authentication methods.
// 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));
@ -642,8 +597,8 @@ namespace OpenIddict.Server.Owin
}
// Attach the basic authentication credentials to the request message.
context.Request.ClientId = UnescapeDataString(data.Substring(0, index));
context.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1));
context.Transaction.Request.ClientId = UnescapeDataString(data.Substring(0, index));
context.Transaction.Request.ClientSecret = UnescapeDataString(data.Substring(index + 1));
return default;
}
@ -657,7 +612,7 @@ namespace OpenIddict.Server.Owin
return default;
}
static string UnescapeDataString(string data)
static string? UnescapeDataString(string data)
{
if (string.IsNullOrEmpty(data))
{
@ -687,20 +642,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Request != null, SR.GetResourceString(SR.ID5008));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var request = context.Transaction.GetOwinRequest();
@ -716,7 +667,7 @@ namespace OpenIddict.Server.Owin
}
// 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;
}
@ -742,14 +693,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -779,20 +724,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -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
// 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.
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).
@ -843,14 +784,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -882,7 +817,7 @@ namespace OpenIddict.Server.Owin
{
private readonly IOptionsMonitor<OpenIddictServerOwinOptions> _options;
public AttachWwwAuthenticateHeader([NotNull] IOptionsMonitor<OpenIddictServerOwinOptions> options)
public AttachWwwAuthenticateHeader(IOptionsMonitor<OpenIddictServerOwinOptions> options)
=> _options = options;
/// <summary>
@ -896,20 +831,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -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
// 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.
var scheme = context.Response.Error switch
var scheme = context.Transaction.Response.Error switch
{
Errors.InvalidClient => Schemes.Basic,
@ -950,11 +881,11 @@ namespace OpenIddict.Server.Owin
parameters[Parameters.Realm] = _options.CurrentValue.Realm;
}
foreach (var parameter in context.Response.GetParameters())
foreach (var parameter in context.Transaction.Response.GetParameters())
{
// Note: the error details are only included if the error was not caused by a missing token, as recommended
// by the OAuth 2.0 bearer specification: https://tools.ietf.org/html/rfc6750#section-3.1.
if (string.Equals(context.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
if (string.Equals(context.Transaction.Response.Error, Errors.MissingToken, StringComparison.Ordinal) &&
(string.Equals(parameter.Key, Parameters.Error, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorDescription, StringComparison.Ordinal) ||
string.Equals(parameter.Key, Parameters.ErrorUri, StringComparison.Ordinal)))
@ -963,7 +894,7 @@ namespace OpenIddict.Server.Owin
}
// Ignore values that can't be represented as unique strings.
var value = (string) parameter.Value;
var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value))
{
continue;
@ -1014,14 +945,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1042,7 +967,7 @@ namespace OpenIddict.Server.Owin
return default;
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7141), context.Transaction.Response);
context.HandleRequest();
return default;
@ -1066,14 +991,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1088,10 +1007,10 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
}
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Response);
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Response, new JsonSerializerOptions
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
@ -1129,20 +1048,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -1151,13 +1066,13 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
}
if (string.IsNullOrEmpty(context.Response.Error))
if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{
return default;
}
// Don't return the state originally sent by the client application.
context.Response.State = null;
context.Transaction.Response.State = null;
context.SkipRequest();
@ -1183,20 +1098,16 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response != null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -1205,24 +1116,24 @@ namespace OpenIddict.Server.Owin
throw new InvalidOperationException(SR.GetResourceString(SR.ID1119));
}
if (string.IsNullOrEmpty(context.Response.Error))
if (string.IsNullOrEmpty(context.Transaction.Response.Error))
{
return;
}
// 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 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
// objects that can't be represented as strings.
var value = (string) parameter.Value;
var value = (string?) parameter.Value;
if (string.IsNullOrEmpty(value))
{
continue;
@ -1264,14 +1175,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1286,7 +1191,7 @@ namespace OpenIddict.Server.Owin
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))
{
response.Redirect(properties.RedirectUri);
@ -1317,14 +1222,8 @@ namespace OpenIddict.Server.Owin
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(TContext context)
{
if (context == null)
{

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

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

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

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

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

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

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

@ -94,10 +94,9 @@ namespace OpenIddict.Server.Owin
public bool EnableLogoutEndpointCaching { get; set; }
/// <summary>
/// Gets or sets the optional "realm" value returned to
/// the caller as part of the WWW-Authenticate header.
/// Gets or sets the optional "realm" value returned to the caller as part of the WWW-Authenticate header.
/// </summary>
public string Realm { get; set; }
public string? Realm { get; set; }
/// <summary>
/// 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 JetBrains.Annotations;
using static OpenIddict.Server.OpenIddictServerEvents;
namespace OpenIddict.Server
{
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 JetBrains.Annotations;
using static OpenIddict.Server.OpenIddictServerEvents;
namespace OpenIddict.Server
@ -23,6 +22,6 @@ namespace OpenIddict.Server
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
ValueTask HandleAsync([NotNull] TContext context);
ValueTask HandleAsync(TContext context);
}
}

3
src/OpenIddict.Server/IOpenIddictServerHandlerFilter.cs

@ -5,13 +5,12 @@
*/
using System.Threading.Tasks;
using JetBrains.Annotations;
using static OpenIddict.Server.OpenIddictServerEvents;
namespace OpenIddict.Server
{
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>
<TargetFrameworks>net461;net472;net48;netcoreapp2.1;netcoreapp3.1;netstandard2.0;netstandard2.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>

133
src/OpenIddict.Server/OpenIddictServerBuilder.cs

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

5
src/OpenIddict.Server/OpenIddictServerConfiguration.cs

@ -7,7 +7,6 @@
using System;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using static OpenIddict.Abstractions.OpenIddictConstants;
@ -28,7 +27,7 @@ namespace OpenIddict.Server
/// </summary>
/// <param name="name">The name of the options instance to configure, if applicable.</param>
/// <param name="options">The options instance to initialize.</param>
public void PostConfigure([CanBeNull] string name, [NotNull] OpenIddictServerOptions options)
public void PostConfigure(string name, OpenIddictServerOptions options)
{
if (options == null)
{
@ -300,7 +299,7 @@ namespace OpenIddict.Server
(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
// 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.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using static OpenIddict.Server.OpenIddictServerEvents;
@ -25,16 +24,16 @@ namespace OpenIddict.Server
/// Creates a new instance of the <see cref="OpenIddictServerDispatcher"/> class.
/// </summary>
public OpenIddictServerDispatcher(
[NotNull] ILogger<OpenIddictServerDispatcher> logger,
[NotNull] IOptionsMonitor<OpenIddictServerOptions> options,
[NotNull] IServiceProvider provider)
ILogger<OpenIddictServerDispatcher> logger,
IOptionsMonitor<OpenIddictServerOptions> options,
IServiceProvider provider)
{
_logger = logger;
_options = options;
_provider = provider;
}
public async ValueTask DispatchAsync<TContext>([NotNull] TContext context) where TContext : BaseContext
public async ValueTask DispatchAsync<TContext>(TContext context) where TContext : BaseContext
{
if (context == null)
{

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

@ -6,7 +6,7 @@
using System;
using System.Security.Claims;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
using SR = OpenIddict.Abstractions.OpenIddictResources;
namespace OpenIddict.Server
@ -22,10 +22,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractAuthorizationRequestContext"/> class.
/// </summary>
public ExtractAuthorizationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractAuthorizationRequestContext(OpenIddictServerTransaction 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>
@ -37,22 +46,31 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateAuthorizationRequestContext"/> class.
/// </summary>
public ValidateAuthorizationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateAuthorizationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
// Infer the redirect_uri from the value specified by the client application.
=> RedirectUri = Request?.RedirectUri;
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets the client_id specified by the client application.
/// </summary>
public string ClientId => Request.ClientId;
public string? ClientId => Request?.ClientId;
/// <summary>
/// Gets the redirect_uri specified by the client application.
/// If it's not provided by the client, it must be set by
/// the user code by calling <see cref="SetRedirectUri(string)"/>.
/// </summary>
public string RedirectUri { get; private set; }
public string? RedirectUri { get; private set; }
/// <summary>
/// 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
// 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))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1100));
@ -86,11 +104,20 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleAuthorizationRequestContext"/> class.
/// </summary>
public HandleAuthorizationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleAuthorizationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary>
@ -106,36 +133,54 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyAuthorizationResponseContext"/> class.
/// </summary>
public ApplyAuthorizationResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyAuthorizationResponseContext(OpenIddictServerTransaction 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>
/// Gets or sets the security principal.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// Gets the access code expected to
/// be returned to the client application.
/// Depending on the flow, it may be null.
/// </summary>
public string AccessToken => Response.AccessToken;
public string? AccessToken => Response?.AccessToken;
/// <summary>
/// Gets the authorization code expected to
/// be returned to the client application.
/// Depending on the flow, it may be null.
/// </summary>
public string AuthorizationCode => Response.Code;
public string? AuthorizationCode => Response?.Code;
/// <summary>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </summary>
public string Error => Response.Error;
public string? Error => Response?.Error;
/// <summary>
/// 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
/// an untrusted address, which would result in an "open redirection" vulnerability.
/// </summary>
public string RedirectUri { get; set; }
public string? RedirectUri { get; set; }
/// <summary>
/// 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.
/// </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 JetBrains.Annotations;
using OpenIddict.Abstractions;
namespace OpenIddict.Server
{
@ -20,10 +20,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractDeviceRequestContext"/> class.
/// </summary>
public ExtractDeviceRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractDeviceRequestContext(OpenIddictServerTransaction 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>
@ -35,10 +44,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateDeviceRequestContext"/> class.
/// </summary>
public ValidateDeviceRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateDeviceRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -50,10 +68,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleDeviceRequestContext"/> class.
/// </summary>
public HandleDeviceRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleDeviceRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -64,17 +91,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyDeviceResponseContext"/> class.
/// </summary>
public ApplyDeviceResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyDeviceResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </summary>
public string Error => Response.Error;
public string? Error => Response.Error;
}
/// <summary>
@ -86,10 +131,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractVerificationRequestContext"/> class.
/// </summary>
public ExtractVerificationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractVerificationRequestContext(OpenIddictServerTransaction 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>
@ -101,15 +155,24 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateVerificationRequestContext"/> class.
/// </summary>
public ValidateVerificationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateVerificationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal extracted from the user code.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
}
/// <summary>
@ -121,10 +184,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleVerificationRequestContext"/> class.
/// </summary>
public HandleVerificationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleVerificationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -135,17 +207,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyVerificationResponseContext"/> class.
/// </summary>
public ApplyVerificationResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyVerificationResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </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.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions;
@ -23,10 +22,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractConfigurationRequestContext"/> class.
/// </summary>
public ExtractConfigurationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractConfigurationRequestContext(OpenIddictServerTransaction 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>
@ -38,10 +46,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateConfigurationRequestContext"/> class.
/// </summary>
public ValidateConfigurationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateConfigurationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -53,11 +70,20 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleConfigurationRequestContext"/> class.
/// </summary>
public HandleConfigurationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleConfigurationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets the additional parameters returned to the client application.
/// </summary>
@ -67,42 +93,42 @@ namespace OpenIddict.Server
/// <summary>
/// Gets or sets the authorization endpoint address.
/// </summary>
public Uri AuthorizationEndpoint { get; set; }
public Uri? AuthorizationEndpoint { get; set; }
/// <summary>
/// Gets or sets the JWKS endpoint address.
/// </summary>
public Uri CryptographyEndpoint { get; set; }
public Uri? CryptographyEndpoint { get; set; }
/// <summary>
/// Gets or sets the device endpoint address.
/// </summary>
public Uri DeviceEndpoint { get; set; }
public Uri? DeviceEndpoint { get; set; }
/// <summary>
/// Gets or sets the introspection endpoint address.
/// </summary>
public Uri IntrospectionEndpoint { get; set; }
public Uri? IntrospectionEndpoint { get; set; }
/// <summary>
/// Gets or sets the logout endpoint address.
/// </summary>
public Uri LogoutEndpoint { get; set; }
public Uri? LogoutEndpoint { get; set; }
/// <summary>
/// Gets or sets the revocation endpoint address.
/// </summary>
public Uri RevocationEndpoint { get; set; }
public Uri? RevocationEndpoint { get; set; }
/// <summary>
/// Gets or sets the token endpoint address.
/// </summary>
public Uri TokenEndpoint { get; set; }
public Uri? TokenEndpoint { get; set; }
/// <summary>
/// Gets or sets the userinfo endpoint address.
/// </summary>
public Uri UserinfoEndpoint { get; set; }
public Uri? UserinfoEndpoint { get; set; }
/// <summary>
/// Gets the list of claims supported by the authorization server.
@ -178,17 +204,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyConfigurationResponseContext"/> class.
/// </summary>
public ApplyConfigurationResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyConfigurationResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </summary>
public string Error => Response.Error;
public string? Error => Response.Error;
}
/// <summary>
@ -200,10 +244,28 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractCryptographyRequestContext"/> class.
/// </summary>
public ExtractCryptographyRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractCryptographyRequestContext(OpenIddictServerTransaction 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>
@ -215,10 +277,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateCryptographyRequestContext"/> class.
/// </summary>
public ValidateCryptographyRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateCryptographyRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
}
/// <summary>
@ -230,11 +301,20 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleCryptographyRequestContext"/> class.
/// </summary>
public HandleCryptographyRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleCryptographyRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets the list of JSON Web Keys exposed by the JWKS endpoint.
/// </summary>
@ -249,17 +329,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyCryptographyResponseContext"/> class.
/// </summary>
public ApplyCryptographyResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyCryptographyResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </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 JetBrains.Annotations;
using OpenIddict.Abstractions;
namespace OpenIddict.Server
{
@ -20,10 +20,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractTokenRequestContext"/> class.
/// </summary>
public ExtractTokenRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractTokenRequestContext(OpenIddictServerTransaction 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>
@ -35,16 +44,25 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateTokenRequestContext"/> class.
/// </summary>
public ValidateTokenRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateTokenRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal extracted from the authorization
/// code or the refresh token, if applicable to the current token request.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
}
/// <summary>
@ -56,11 +74,20 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleTokenRequestContext"/> class.
/// </summary>
public HandleTokenRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleTokenRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Allows OpenIddict to return a sign-in response using the specified principal.
/// </summary>
@ -76,22 +103,40 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyTokenResponseContext"/> class.
/// </summary>
public ApplyTokenResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyTokenResponseContext(OpenIddictServerTransaction 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>
/// Gets or sets the security principal used to forge the token response.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </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.Collections.Generic;
using System.Security.Claims;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
namespace OpenIddict.Server
@ -23,10 +22,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractIntrospectionRequestContext"/> class.
/// </summary>
public ExtractIntrospectionRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractIntrospectionRequestContext(OpenIddictServerTransaction 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>
@ -38,21 +46,30 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateIntrospectionRequestContext"/> class.
/// </summary>
public ValidateIntrospectionRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateIntrospectionRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets the optional token_type_hint parameter extracted from the
/// introspection request, or <c>null</c> if it cannot be found.
/// </summary>
public string TokenTypeHint => Request.TokenTypeHint;
public string? TokenTypeHint => Request?.TokenTypeHint;
/// <summary>
/// Gets or sets the security principal extracted from the introspected token, if available.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
}
/// <summary>
@ -64,15 +81,24 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleIntrospectionRequestContext"/> class.
/// </summary>
public HandleIntrospectionRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleIntrospectionRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal extracted from the introspected token.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// 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);
/// <summary>
/// Gets or sets the "client_id" claim
/// returned to the caller, if applicable.
/// Gets or sets the "client_id" claim returned to the caller, if applicable.
/// </summary>
public string ClientId { get; set; }
public string? ClientId { get; set; }
/// <summary>
/// Gets or sets the "exp" claim
@ -120,31 +145,31 @@ namespace OpenIddict.Server
/// Gets or sets the "sub" claim
/// returned to the caller, if applicable.
/// </summary>
public string Subject { get; set; }
public string? Subject { get; set; }
/// <summary>
/// Gets or sets the "jti" claim
/// returned to the caller, if applicable.
/// </summary>
public string TokenId { get; set; }
public string? TokenId { get; set; }
/// <summary>
/// Gets or sets the "token_type" claim
/// returned to the caller, if applicable.
/// </summary>
public string TokenType { get; set; }
public string? TokenType { get; set; }
/// <summary>
/// Gets or sets the "token_usage" claim
/// returned to the caller, if applicable.
/// </summary>
public string TokenUsage { get; set; }
public string? TokenUsage { get; set; }
/// <summary>
/// Gets or sets the "username" claim
/// returned to the caller, if applicable.
/// </summary>
public string Username { get; set; }
public string? Username { get; set; }
}
/// <summary>
@ -155,17 +180,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyIntrospectionResponseContext"/> class.
/// </summary>
public ApplyIntrospectionResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyIntrospectionResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </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.Collections.Generic;
using System.Security.Claims;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
namespace OpenIddict.Server
{
@ -22,10 +22,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractRevocationRequestContext"/> class.
/// </summary>
public ExtractRevocationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractRevocationRequestContext(OpenIddictServerTransaction 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>
@ -37,21 +46,30 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateRevocationRequestContext"/> class.
/// </summary>
public ValidateRevocationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateRevocationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets the optional token_type_hint parameter extracted from the
/// revocation request, or <c>null</c> if it cannot be found.
/// </summary>
public string TokenTypeHint => Request.TokenTypeHint;
public string? TokenTypeHint => Request.TokenTypeHint;
/// <summary>
/// Gets or sets the security principal extracted from the revoked token, if available.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
}
/// <summary>
@ -63,15 +81,24 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleRevocationRequestContext"/> class.
/// </summary>
public HandleRevocationRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleRevocationRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal extracted from the revoked token.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// Gets the authentication ticket.
@ -88,17 +115,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyRevocationResponseContext"/> class.
/// </summary>
public ApplyRevocationResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyRevocationResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </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 JetBrains.Annotations;
using OpenIddict.Abstractions;
using SR = OpenIddict.Abstractions.OpenIddictResources;
namespace OpenIddict.Server
@ -21,10 +21,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractLogoutRequestContext"/> class.
/// </summary>
public ExtractLogoutRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractLogoutRequestContext(OpenIddictServerTransaction 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>
@ -36,15 +45,24 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateLogoutRequestContext"/> class.
/// </summary>
public ValidateLogoutRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateLogoutRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
// Infer the post_logout_redirect_uri from the value specified by the client application.
=> PostLogoutRedirectUri = Request?.PostLogoutRedirectUri;
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets the post_logout_redirect_uri specified by the client application.
/// </summary>
public string PostLogoutRedirectUri { get; private set; }
public string? PostLogoutRedirectUri { get; private set; }
/// <summary>
/// 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
// 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))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1102));
@ -78,11 +96,20 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleLogoutRequestContext"/> class.
/// </summary>
public HandleLogoutRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleLogoutRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets a boolean indicating whether a sign-out should be triggered.
/// </summary>
@ -102,17 +129,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyLogoutResponseContext"/> class.
/// </summary>
public ApplyLogoutResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyLogoutResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </summary>
public string Error => Response.Error;
public string? Error => Response.Error;
/// <summary>
/// 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
/// an untrusted address, which would result in an "open redirection" vulnerability.
/// </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.Security.Claims;
using System.Text.Json;
using JetBrains.Annotations;
using OpenIddict.Abstractions;
namespace OpenIddict.Server
@ -24,10 +23,19 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ExtractUserinfoRequestContext"/> class.
/// </summary>
public ExtractUserinfoRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ExtractUserinfoRequestContext(OpenIddictServerTransaction 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>
@ -39,15 +47,24 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ValidateUserinfoRequestContext"/> class.
/// </summary>
public ValidateUserinfoRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ValidateUserinfoRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal extracted from the access token, if available.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
}
/// <summary>
@ -59,15 +76,24 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="HandleUserinfoRequestContext"/> class.
/// </summary>
public HandleUserinfoRequestContext([NotNull] OpenIddictServerTransaction transaction)
public HandleUserinfoRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal extracted from the access token.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// 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"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string BirthDate { get; set; }
public string? BirthDate { get; set; }
/// <summary>
/// Gets or sets the value used for the "email" claim.
/// Note: this value should only be populated if the "email"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string Email { get; set; }
public string? Email { get; set; }
/// <summary>
/// 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"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string FamilyName { get; set; }
public string? FamilyName { get; set; }
/// <summary>
/// Gets or sets the value used for the "given_name" claim.
/// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string GivenName { get; set; }
public string? GivenName { get; set; }
/// <summary>
/// Gets or sets the value used for the "phone_number" claim.
/// Note: this value should only be populated if the "phone"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string PhoneNumber { get; set; }
public string? PhoneNumber { get; set; }
/// <summary>
/// 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"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string PreferredUsername { get; set; }
public string? PreferredUsername { get; set; }
/// <summary>
/// Gets or sets the value used for the "profile" claim.
/// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string Profile { get; set; }
public string? Profile { get; set; }
/// <summary>
/// Gets or sets the unique value
/// used for the mandatory "sub" claim.
/// </summary>
public string Subject { get; set; }
public string? Subject { get; set; }
/// <summary>
/// Gets or sets the value used for the "website" claim.
/// Note: this value should only be populated if the "profile"
/// scope was requested and accepted by the resource owner.
/// </summary>
public string Website { get; set; }
public string? Website { get; set; }
}
/// <summary>
@ -172,17 +198,35 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ApplyUserinfoResponseContext"/> class.
/// </summary>
public ApplyUserinfoResponseContext([NotNull] OpenIddictServerTransaction transaction)
public ApplyUserinfoResponseContext(OpenIddictServerTransaction 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>
/// Gets the error code returned to the client application.
/// When the response indicates a successful response,
/// this property returns <c>null</c>.
/// </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.ComponentModel;
using System.Security.Claims;
using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
@ -25,7 +24,7 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="BaseContext"/> class.
/// </summary>
protected BaseContext([NotNull] OpenIddictServerTransaction transaction)
protected BaseContext(OpenIddictServerTransaction transaction)
=> Transaction = transaction ?? throw new ArgumentNullException(nameof(transaction));
/// <summary>
@ -36,7 +35,7 @@ namespace OpenIddict.Server
/// <summary>
/// Gets or sets the issuer address associated with the current transaction, if available.
/// </summary>
public Uri Issuer
public Uri? Issuer
{
get => Transaction.Issuer;
set => Transaction.Issuer = value;
@ -65,24 +64,6 @@ namespace OpenIddict.Server
/// Gets the OpenIddict server options.
/// </summary>
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>
@ -94,7 +75,7 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="BaseRequestContext"/> class.
/// </summary>
protected BaseRequestContext([NotNull] OpenIddictServerTransaction transaction)
protected BaseRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
@ -133,7 +114,7 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="BaseValidatingClientContext"/> class.
/// </summary>
protected BaseValidatingClientContext([NotNull] OpenIddictServerTransaction transaction)
protected BaseValidatingClientContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
@ -143,14 +124,14 @@ namespace OpenIddict.Server
/// The authorization server application is responsible for
/// validating this value to ensure it identifies a registered client.
/// </summary>
public string ClientId => (string) Request[OpenIddictConstants.Parameters.ClientId];
public string? ClientId => Transaction.Request?.ClientId;
/// <summary>
/// Gets the "client_secret" parameter for the current request.
/// The authorization server application is responsible for
/// validating this value to ensure it identifies a registered client.
/// </summary>
public string ClientSecret => (string) Request[OpenIddictConstants.Parameters.ClientSecret];
public string? ClientSecret => Transaction.Request?.ClientSecret;
}
/// <summary>
@ -162,7 +143,7 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="BaseValidatingContext"/> class.
/// </summary>
protected BaseValidatingContext([NotNull] OpenIddictServerTransaction transaction)
protected BaseValidatingContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
@ -175,17 +156,17 @@ namespace OpenIddict.Server
/// <summary>
/// Gets or sets the "error" parameter returned to the client application.
/// </summary>
public string Error { get; private set; }
public string? Error { get; private set; }
/// <summary>
/// Gets or sets the "error_description" parameter returned to the client application.
/// </summary>
public string ErrorDescription { get; private set; }
public string? ErrorDescription { get; private set; }
/// <summary>
/// Gets or sets the "error_uri" parameter returned to the client application.
/// </summary>
public string ErrorUri { get; private set; }
public string? ErrorUri { get; private set; }
/// <summary>
/// Rejects the request.
@ -196,7 +177,7 @@ namespace OpenIddict.Server
/// Rejects the request.
/// </summary>
/// <param name="error">The "error" parameter returned to the client application.</param>
public virtual void Reject(string error)
public virtual void Reject(string? error)
{
Error = error;
@ -208,7 +189,7 @@ namespace OpenIddict.Server
/// </summary>
/// <param name="error">The "error" parameter returned to the client application.</param>
/// <param name="description">The "error_description" parameter returned to the client application.</param>
public virtual void Reject(string error, string description)
public virtual void Reject(string? error, string? description)
{
Error = error;
ErrorDescription = description;
@ -222,7 +203,7 @@ namespace OpenIddict.Server
/// <param name="error">The "error" parameter returned to the client application.</param>
/// <param name="description">The "error_description" parameter returned to the client application.</param>
/// <param name="uri">The "error_uri" parameter returned to the client application.</param>
public virtual void Reject(string error, string description, string uri)
public virtual void Reject(string? error, string? description, string? uri)
{
Error = error;
ErrorDescription = description;
@ -241,7 +222,7 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="BaseValidatingTicketContext"/> class.
/// </summary>
protected BaseValidatingTicketContext([NotNull] OpenIddictServerTransaction transaction)
protected BaseValidatingTicketContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
@ -249,12 +230,12 @@ namespace OpenIddict.Server
/// <summary>
/// Gets or sets the security principal.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// Gets the client identifier, or <c>null</c> if the client application is unknown.
/// </summary>
public string ClientId => Request.ClientId;
public string? ClientId => Transaction.Request?.ClientId;
}
/// <summary>
@ -265,7 +246,7 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ProcessRequestContext"/> class.
/// </summary>
public ProcessRequestContext([NotNull] OpenIddictServerTransaction transaction)
public ProcessRequestContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
@ -279,10 +260,28 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ProcessErrorContext"/> class.
/// </summary>
public ProcessErrorContext([NotNull] OpenIddictServerTransaction transaction)
public ProcessErrorContext(OpenIddictServerTransaction 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>
@ -293,25 +292,34 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ProcessAuthenticationContext"/> class.
/// </summary>
public ProcessAuthenticationContext([NotNull] OpenIddictServerTransaction transaction)
public ProcessAuthenticationContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the security principal.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
public ClaimsPrincipal? Principal { get; set; }
/// <summary>
/// Gets or sets the token to validate.
/// </summary>
public string Token { get; set; }
public string? Token { get; set; }
/// <summary>
/// Gets or sets the expected type of the token.
/// </summary>
public string TokenType { get; set; }
public string? TokenType { get; set; }
}
/// <summary>
@ -322,10 +330,28 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ProcessChallengeContext"/> class.
/// </summary>
public ProcessChallengeContext([NotNull] OpenIddictServerTransaction transaction)
public ProcessChallengeContext(OpenIddictServerTransaction 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>
@ -336,11 +362,29 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ProcessSignInContext"/> class.
/// </summary>
public ProcessSignInContext([NotNull] OpenIddictServerTransaction transaction)
public ProcessSignInContext(OpenIddictServerTransaction transaction)
: base(transaction)
{
}
/// <summary>
/// Gets or sets the request.
/// </summary>
public OpenIddictRequest Request
{
get => Transaction.Request!;
set => Transaction.Request = value;
}
/// <summary>
/// Gets or sets the response.
/// </summary>
public OpenIddictResponse Response
{
get => Transaction.Response!;
set => Transaction.Response = value;
}
/// <summary>
/// Gets or sets a boolean indicating whether an access token
/// should be returned to the client application.
@ -393,37 +437,37 @@ namespace OpenIddict.Server
/// Gets or sets the principal containing the claims that
/// will be used to create the access token, if applicable.
/// </summary>
public ClaimsPrincipal AccessTokenPrincipal { get; set; }
public ClaimsPrincipal? AccessTokenPrincipal { get; set; }
/// <summary>
/// Gets or sets the principal containing the claims that
/// will be used to create the authorization code, if applicable.
/// </summary>
public ClaimsPrincipal AuthorizationCodePrincipal { get; set; }
public ClaimsPrincipal? AuthorizationCodePrincipal { get; set; }
/// <summary>
/// Gets or sets the principal containing the claims that
/// will be used to create the device code, if applicable.
/// </summary>
public ClaimsPrincipal DeviceCodePrincipal { get; set; }
public ClaimsPrincipal? DeviceCodePrincipal { get; set; }
/// <summary>
/// Gets or sets the principal containing the claims that
/// will be used to create the identity token, if applicable.
/// </summary>
public ClaimsPrincipal IdentityTokenPrincipal { get; set; }
public ClaimsPrincipal? IdentityTokenPrincipal { get; set; }
/// <summary>
/// Gets or sets the principal containing the claims that
/// will be used to create the refresh token, if applicable.
/// </summary>
public ClaimsPrincipal RefreshTokenPrincipal { get; set; }
public ClaimsPrincipal? RefreshTokenPrincipal { get; set; }
/// <summary>
/// Gets or sets the principal containing the claims that
/// will be used to create the user code, if applicable.
/// </summary>
public ClaimsPrincipal UserCodePrincipal { get; set; }
public ClaimsPrincipal? UserCodePrincipal { get; set; }
}
/// <summary>
@ -434,10 +478,28 @@ namespace OpenIddict.Server
/// <summary>
/// Creates a new instance of the <see cref="ProcessSignOutContext"/> class.
/// </summary>
public ProcessSignOutContext([NotNull] OpenIddictServerTransaction transaction)
public ProcessSignOutContext(OpenIddictServerTransaction 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.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging.Abstractions;
@ -30,7 +29,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="builder">The services builder used by OpenIddict to register new services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public static OpenIddictServerBuilder AddServer([NotNull] this OpenIddictBuilder builder)
public static OpenIddictServerBuilder AddServer(this OpenIddictBuilder builder)
{
if (builder == null)
{
@ -106,9 +105,7 @@ namespace Microsoft.Extensions.DependencyInjection
/// <param name="configuration">The configuration delegate used to configure the server services.</param>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref="OpenIddictBuilder"/>.</returns>
public static OpenIddictBuilder AddServer(
[NotNull] this OpenIddictBuilder builder,
[NotNull] Action<OpenIddictServerBuilder> configuration)
public static OpenIddictBuilder AddServer(this OpenIddictBuilder builder, Action<OpenIddictServerBuilder> configuration)
{
if (builder == null)
{

7
src/OpenIddict.Server/OpenIddictServerFactory.cs

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

5
src/OpenIddict.Server/OpenIddictServerHandler.cs

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

15
src/OpenIddict.Server/OpenIddictServerHandlerDescriptor.cs

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

65
src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs

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

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

@ -7,9 +7,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
@ -71,7 +71,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractAuthorizationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractAuthorizationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -85,14 +85,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -139,7 +133,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateAuthorizationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateAuthorizationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -153,14 +147,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
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
// 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)
{
@ -211,7 +199,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleAuthorizationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleAuthorizationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -225,14 +213,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -306,7 +288,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyAuthorizationResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyAuthorizationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -320,14 +302,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -368,14 +344,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -413,14 +383,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -458,14 +422,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -504,14 +462,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -547,7 +499,7 @@ namespace OpenIddict.Server
// To ensure relative redirect_uris are correctly rejected on these platforms,
// an additional check using IsWellFormedOriginalString() is made here.
// See https://github.com/dotnet/corefx/issues/22098 for more information.
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);
@ -591,14 +543,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -650,14 +596,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -736,14 +676,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -791,14 +725,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -845,14 +773,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -892,14 +814,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -990,7 +906,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1004,20 +920,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1043,7 +955,7 @@ namespace OpenIddict.Server
public ValidateClientType() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientType([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1057,20 +969,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1105,7 +1013,7 @@ namespace OpenIddict.Server
public ValidateClientRedirectUri() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientRedirectUri([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientRedirectUri(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1119,20 +1027,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1184,7 +1088,7 @@ namespace OpenIddict.Server
public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopes([NotNull] IOpenIddictScopeManager scopeManager)
public ValidateScopes(IOpenIddictScopeManager scopeManager)
=> _scopeManager = scopeManager;
/// <summary>
@ -1199,14 +1103,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
@ -1221,7 +1119,11 @@ namespace OpenIddict.Server
{
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([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1264,20 +1166,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1308,7 +1206,7 @@ namespace OpenIddict.Server
public ValidateGrantTypePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateGrantTypePermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateGrantTypePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1323,20 +1221,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1409,7 +1303,7 @@ namespace OpenIddict.Server
public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopePermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateScopePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1424,20 +1318,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1479,7 +1369,7 @@ namespace OpenIddict.Server
public ValidateProofKeyForCodeExchangeRequirement() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateProofKeyForCodeExchangeRequirement([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateProofKeyForCodeExchangeRequirement(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1493,20 +1383,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateAuthorizationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context)
{
if (context == null)
{
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,
// whether the proof key for code exchange requirement is enforced or not.
if (!string.IsNullOrEmpty(context.Request.CodeChallenge))
@ -1549,14 +1435,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
if (context == null)
{
@ -1569,7 +1449,7 @@ namespace OpenIddict.Server
}
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
// is returned from the ExtractAuthorizationRequest/ValidateAuthorizationRequest events).
@ -1598,14 +1478,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
if (context == null)
{
@ -1646,14 +1520,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyAuthorizationResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyAuthorizationResponseContext context)
{
if (context == null)
{

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

@ -7,9 +7,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Security.Claims;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
@ -69,7 +69,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractDeviceRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractDeviceRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -83,14 +83,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -137,7 +131,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateDeviceRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateDeviceRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -151,14 +145,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -200,7 +188,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleDeviceRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleDeviceRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -214,14 +202,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -256,7 +238,7 @@ namespace OpenIddict.Server
{
// Note: no authentication type is deliberately specified to represent an unauthenticated identity.
var principal = new ClaimsPrincipal(new ClaimsIdentity());
principal.SetScopes(context.Request.GetScopes());
principal.SetScopes(notification.Request.GetScopes());
notification.Principal = principal;
}
@ -299,7 +281,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyDeviceResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyDeviceResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -313,14 +295,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -361,14 +337,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
@ -402,7 +372,7 @@ namespace OpenIddict.Server
public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopes([NotNull] IOpenIddictScopeManager scopeManager)
public ValidateScopes(IOpenIddictScopeManager scopeManager)
=> _scopeManager = scopeManager;
/// <summary>
@ -417,14 +387,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
@ -439,7 +403,11 @@ namespace OpenIddict.Server
{
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([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -482,20 +450,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
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.
// If no entity can be found, this likely indicates that the client_id is invalid.
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([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -538,20 +502,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -599,7 +559,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -614,29 +574,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
}
// If the application is not a public client, validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) &&
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
// If the application is a public client, don't validate the client secret.
if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
{
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);
@ -660,7 +622,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -676,20 +638,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -721,7 +679,7 @@ namespace OpenIddict.Server
public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopePermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateScopePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -737,20 +695,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateDeviceRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateDeviceRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -788,7 +742,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractVerificationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractVerificationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -802,14 +756,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -856,7 +804,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateVerificationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateVerificationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -870,14 +818,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -919,7 +861,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleVerificationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleVerificationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -933,14 +875,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -1014,7 +950,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyVerificationResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyVerificationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -1028,14 +964,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1068,7 +998,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public AttachUserCodePrincipal([NotNull] IOpenIddictServerDispatcher dispatcher)
public AttachUserCodePrincipal(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -1081,14 +1011,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] HandleVerificationRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(HandleVerificationRequestContext context)
{
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
// 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)
{

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

@ -13,7 +13,6 @@ using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions;
@ -74,7 +73,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractConfigurationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractConfigurationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -88,14 +87,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -142,7 +135,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateConfigurationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateConfigurationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -156,14 +149,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -205,7 +192,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleConfigurationRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleConfigurationRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -219,14 +206,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -286,7 +267,7 @@ namespace OpenIddict.Server
response.SetParameter(metadata.Key, metadata.Value);
}
context.Response = response;
context.Transaction.Response = response;
}
}
@ -297,7 +278,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyConfigurationResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyConfigurationResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -311,14 +292,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -359,14 +334,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -402,7 +371,7 @@ namespace OpenIddict.Server
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 (endpoint == null)
@ -456,14 +425,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -491,14 +454,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -526,14 +483,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -562,14 +513,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -614,14 +559,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -649,14 +588,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -684,14 +617,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -719,14 +646,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -754,14 +675,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -826,14 +741,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleConfigurationRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleConfigurationRequestContext context)
{
if (context == null)
{
@ -857,7 +766,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractCryptographyRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractCryptographyRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -871,14 +780,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -925,7 +828,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateCryptographyRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateCryptographyRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -939,14 +842,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -988,7 +885,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleCryptographyRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleCryptographyRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -1002,14 +899,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -1111,7 +1002,7 @@ namespace OpenIddict.Server
var response = new OpenIddictResponse();
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;
public ApplyCryptographyResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyCryptographyResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -1136,14 +1027,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -1184,14 +1069,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleCryptographyRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleCryptographyRequestContext context)
{
if (context == null)
{

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

@ -10,7 +10,6 @@ using System.Collections.Immutable;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.Abstractions;
@ -18,6 +17,7 @@ using static OpenIddict.Abstractions.OpenIddictConstants;
using static OpenIddict.Server.OpenIddictServerEvents;
using static OpenIddict.Server.OpenIddictServerHandlerFilters;
using SR = OpenIddict.Abstractions.OpenIddictResources;
using System.Diagnostics;
#if !SUPPORTS_TIME_CONSTANT_COMPARISONS
using Org.BouncyCastle.Utilities;
@ -77,7 +77,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractTokenRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractTokenRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -91,14 +91,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -145,7 +139,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateTokenRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateTokenRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -159,14 +153,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
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
// 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)
{
@ -212,7 +200,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleTokenRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleTokenRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -226,14 +214,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -307,7 +289,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyTokenResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyTokenResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -321,14 +303,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -369,14 +345,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -437,14 +407,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -492,14 +456,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -539,14 +497,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -585,14 +537,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -630,14 +576,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -677,14 +617,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -719,7 +653,7 @@ namespace OpenIddict.Server
public ValidateScopes() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopes([NotNull] IOpenIddictScopeManager scopeManager)
public ValidateScopes(IOpenIddictScopeManager scopeManager)
=> _scopeManager = scopeManager;
/// <summary>
@ -734,14 +668,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -756,7 +684,11 @@ namespace OpenIddict.Server
{
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([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -799,20 +731,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
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.
// If no entity can be found, this likely indicates that the client_id is invalid.
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([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -855,20 +783,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -928,7 +852,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -943,29 +867,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
}
// If the application is not a public client, validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) &&
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
// If the application is a public client, don't validate the client secret.
if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
{
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);
@ -989,7 +915,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1005,20 +931,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1050,7 +972,7 @@ namespace OpenIddict.Server
public ValidateGrantTypePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateGrantTypePermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateGrantTypePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1066,20 +988,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1125,7 +1043,7 @@ namespace OpenIddict.Server
public ValidateScopePermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateScopePermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateScopePermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1141,20 +1059,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1196,7 +1110,7 @@ namespace OpenIddict.Server
public ValidateProofKeyForCodeExchangeRequirement() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateProofKeyForCodeExchangeRequirement([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateProofKeyForCodeExchangeRequirement(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1211,14 +1125,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -1237,6 +1145,8 @@ namespace OpenIddict.Server
return;
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -1264,7 +1174,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -1277,14 +1187,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateTokenRequestContext context)
{
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
// 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)
{
@ -1347,14 +1251,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -1368,6 +1266,8 @@ namespace OpenIddict.Server
return default;
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
var presenters = context.Principal.GetPresenters();
if (presenters.IsDefaultOrEmpty)
{
@ -1437,14 +1337,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -1456,6 +1350,8 @@ namespace OpenIddict.Server
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.
// 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
@ -1510,14 +1406,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
@ -1529,6 +1419,8 @@ namespace OpenIddict.Server
return default;
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// Note: the ValidateProofKeyForCodeExchangeRequirement handler (invoked earlier) ensures
// 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
@ -1630,23 +1522,26 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
public ValueTask HandleAsync([NotNull] ValidateTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateTokenRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (string.IsNullOrEmpty(context.Request.Scope))
if (!context.Request.IsAuthorizationCodeGrantType() && !context.Request.IsRefreshTokenGrantType())
{
return default;
}
if (!context.Request.IsAuthorizationCodeGrantType() && !context.Request.IsRefreshTokenGrantType())
if (string.IsNullOrEmpty(context.Request.Scope))
{
return default;
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
// When an explicit scope parameter has been included in the token request
// but was missing from the initial request, the request MUST be rejected.
// See http://tools.ietf.org/html/rfc6749#section-6 for more information.
@ -1697,14 +1592,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleTokenRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleTokenRequestContext context)
{
if (context == null)
{
@ -1717,7 +1606,7 @@ namespace OpenIddict.Server
}
var notification = context.Transaction.GetProperty<ValidateTokenRequestContext>(
typeof(ValidateTokenRequestContext).FullName) ??
typeof(ValidateTokenRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal;

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

@ -6,13 +6,13 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
@ -70,7 +70,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractIntrospectionRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractIntrospectionRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -84,14 +84,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -138,7 +132,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateIntrospectionRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateIntrospectionRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -152,14 +146,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
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
// 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)
{
@ -205,7 +193,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleIntrospectionRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleIntrospectionRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -219,14 +207,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -303,7 +285,7 @@ namespace OpenIddict.Server
response.SetParameter(claim.Key, claim.Value);
}
context.Response = response;
context.Transaction.Response = response;
}
}
@ -314,7 +296,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyIntrospectionResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyIntrospectionResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -328,14 +310,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -376,14 +352,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
@ -421,14 +391,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
@ -461,7 +425,7 @@ namespace OpenIddict.Server
public ValidateClientId() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientId([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientId(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -476,20 +440,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
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.
// If no entity can be found, this likely indicates that the client_id is invalid.
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([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientType(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -532,20 +492,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -593,7 +549,7 @@ namespace OpenIddict.Server
public ValidateClientSecret() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientSecret([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientSecret(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -608,29 +564,31 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1031));
}
// If the application is not a public client, validate the client secret.
if (!await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public) &&
!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
// If the application is a public client, don't validate the client secret.
if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
{
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);
@ -654,7 +612,7 @@ namespace OpenIddict.Server
public ValidateEndpointPermissions() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateEndpointPermissions([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateEndpointPermissions(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -670,20 +628,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID5000(Parameters.ClientId));
var application = await _applicationManager.FindByClientIdAsync(context.ClientId);
if (application == null)
{
@ -711,7 +665,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -724,14 +678,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
@ -782,20 +730,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) &&
!context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode) &&
!context.Principal.HasTokenType(TokenTypeHints.IdToken) &&
@ -834,20 +778,17 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateIntrospectionRequestContext context)
{
if (context == null)
{
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
// listed as a presenter (i.e the party the authorization code was issued to).
if (context.Principal.HasTokenType(TokenTypeHints.AuthorizationCode))
@ -940,14 +881,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionRequestContext context)
{
if (context == null)
{
@ -955,7 +890,7 @@ namespace OpenIddict.Server
}
var notification = context.Transaction.GetProperty<ValidateIntrospectionRequestContext>(
typeof(ValidateIntrospectionRequestContext).FullName) ??
typeof(ValidateIntrospectionRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal;
@ -979,20 +914,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleIntrospectionRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleIntrospectionRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
context.TokenId = context.Principal.GetClaim(Claims.JwtId);
context.TokenUsage = context.Principal.GetTokenType();
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([NotNull] IOpenIddictApplicationManager applicationManager)
public AttachApplicationClaims(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -1043,20 +974,17 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] HandleIntrospectionRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(HandleIntrospectionRequestContext context)
{
if (context == null)
{
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.
if (!context.Principal.HasTokenType(TokenTypeHints.AccessToken) && !context.Principal.HasTokenType(TokenTypeHints.IdToken))
{
@ -1166,14 +1094,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyIntrospectionResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyIntrospectionResponseContext context)
{
if (context == null)
{

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

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

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

@ -6,8 +6,8 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
@ -51,7 +51,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractLogoutRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractLogoutRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -65,14 +65,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -119,7 +113,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateLogoutRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateLogoutRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -133,14 +127,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
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
// 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)
{
@ -186,7 +174,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleLogoutRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleLogoutRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -200,14 +188,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -280,7 +262,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyLogoutResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyLogoutResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -294,14 +276,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -342,14 +318,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateLogoutRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateLogoutRequestContext context)
{
if (context == null)
{
@ -362,7 +332,7 @@ namespace OpenIddict.Server
}
// 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);
@ -398,7 +368,7 @@ namespace OpenIddict.Server
public ValidateClientPostLogoutRedirectUri() => throw new InvalidOperationException(SR.GetResourceString(SR.ID1015));
public ValidateClientPostLogoutRedirectUri([NotNull] IOpenIddictApplicationManager applicationManager)
public ValidateClientPostLogoutRedirectUri(IOpenIddictApplicationManager applicationManager)
=> _applicationManager = applicationManager;
/// <summary>
@ -413,20 +383,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateLogoutRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateLogoutRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(!string.IsNullOrEmpty(context.PostLogoutRedirectUri), SR.FormatID5000(Parameters.PostLogoutRedirectUri));
if (!await ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri))
{
context.Logger.LogError(SR.GetResourceString(SR.ID7128), context.PostLogoutRedirectUri);
@ -473,14 +439,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyLogoutResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyLogoutResponseContext context)
{
if (context == null)
{
@ -493,7 +453,7 @@ namespace OpenIddict.Server
}
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
// an error is returned from the ExtractLogoutRequest/ValidateLogoutRequest events).
@ -521,14 +481,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ApplyLogoutResponseContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ApplyLogoutResponseContext context)
{
if (context == null)
{

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

@ -6,9 +6,9 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;
@ -53,7 +53,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ExtractUserinfoRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ExtractUserinfoRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -67,14 +67,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -121,7 +115,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateUserinfoRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateUserinfoRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -135,14 +129,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
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
// 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)
{
@ -188,7 +176,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public HandleUserinfoRequest([NotNull] IOpenIddictServerDispatcher dispatcher)
public HandleUserinfoRequest(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -202,14 +190,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ProcessRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ProcessRequestContext context)
{
if (context == null)
{
@ -275,7 +257,7 @@ namespace OpenIddict.Server
response.SetParameter(claim.Key, claim.Value);
}
context.Response = response;
context.Transaction.Response = response;
}
}
@ -286,7 +268,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ApplyUserinfoResponse([NotNull] IOpenIddictServerDispatcher dispatcher)
public ApplyUserinfoResponse(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -300,14 +282,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] TContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(TContext context)
{
if (context == null)
{
@ -348,14 +324,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] ValidateUserinfoRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(ValidateUserinfoRequestContext context)
{
if (context == null)
{
@ -384,7 +354,7 @@ namespace OpenIddict.Server
{
private readonly IOpenIddictServerDispatcher _dispatcher;
public ValidateToken([NotNull] IOpenIddictServerDispatcher dispatcher)
public ValidateToken(IOpenIddictServerDispatcher dispatcher)
=> _dispatcher = dispatcher;
/// <summary>
@ -397,14 +367,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public async ValueTask HandleAsync([NotNull] ValidateUserinfoRequestContext context)
/// <inheritdoc/>
public async ValueTask HandleAsync(ValidateUserinfoRequestContext context)
{
if (context == null)
{
@ -456,14 +420,8 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleUserinfoRequestContext context)
{
if (context == null)
{
@ -471,7 +429,7 @@ namespace OpenIddict.Server
}
var notification = context.Transaction.GetProperty<ValidateUserinfoRequestContext>(
typeof(ValidateUserinfoRequestContext).FullName) ??
typeof(ValidateUserinfoRequestContext).FullName!) ??
throw new InvalidOperationException(SR.GetResourceString(SR.ID1006));
context.Principal ??= notification.Principal;
@ -495,20 +453,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleUserinfoRequestContext context)
{
if (context == null)
{
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
// 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
@ -533,20 +487,16 @@ namespace OpenIddict.Server
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync([NotNull] HandleUserinfoRequestContext context)
/// <inheritdoc/>
public ValueTask HandleAsync(HandleUserinfoRequestContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Principal != null, SR.GetResourceString(SR.ID5006));
context.Subject = context.Principal.GetClaim(Claims.Subject);
// 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 JetBrains.Annotations;
using SR = OpenIddict.Abstractions.OpenIddictResources;
namespace OpenIddict.Server
@ -22,8 +21,8 @@ namespace OpenIddict.Server
/// <param name="transaction">The server transaction.</param>
/// <param name="name">The property name.</param>
/// <returns>The property value or <c>null</c> if it couldn't be found.</returns>
public static TProperty GetProperty<TProperty>(
[NotNull] this OpenIddictServerTransaction transaction, [NotNull] string name) where TProperty : class
public static TProperty? GetProperty<TProperty>(
this OpenIddictServerTransaction transaction, string name) where TProperty : class
{
if (transaction == null)
{
@ -52,8 +51,8 @@ namespace OpenIddict.Server
/// <param name="value">The property value.</param>
/// <returns>The server transaction, so that calls can be easily chained.</returns>
public static OpenIddictServerTransaction SetProperty<TProperty>(
[NotNull] this OpenIddictServerTransaction transaction,
[NotNull] string name, [CanBeNull] TProperty value) where TProperty : class
this OpenIddictServerTransaction transaction,
string name, TProperty? value) where TProperty : class
{
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.
/// The URI must be absolute and may contain a path, but no query string or fragment part.
/// </summary>
public Uri Issuer { get; set; }
public Uri? Issuer { get; set; }
/// <summary>
/// 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>
/// Gets or sets the issuer address associated with the current transaction, if available.
/// </summary>
public Uri Issuer { get; set; }
public Uri? Issuer { get; set; }
/// <summary>
/// Gets or sets the localizer associated with the current request.
/// </summary>
public IStringLocalizer Localizer { get; set; }
public IStringLocalizer Localizer { get; set; } = default!;
/// <summary>
/// Gets or sets the logger associated with the current request.
/// </summary>
public ILogger Logger { get; set; }
public ILogger Logger { get; set; } = default!;
/// <summary>
/// Gets or sets the options associated with the current request.
/// </summary>
public OpenIddictServerOptions Options { get; set; }
public OpenIddictServerOptions Options { get; set; } = default!;
/// <summary>
/// Gets the additional properties associated with the current request.
/// </summary>
public IDictionary<string, object> Properties { get; }
= new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public IDictionary<string, object?> Properties { get; }
= new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Gets or sets the current OpenID Connect request.
/// </summary>
public OpenIddictRequest Request { get; set; }
public OpenIddictRequest? Request { get; set; }
/// <summary>
/// Gets or sets the current OpenID Connect response being returned.
/// </summary>
public OpenIddictResponse Response { get; set; }
public OpenIddictResponse? Response { get; set; }
}
}

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

@ -1722,17 +1722,7 @@ namespace OpenIddict.Server.Tests
private class CustomHandler : IOpenIddictServerHandler<CustomContext>
{
/// <summary>
/// Processes the event.
/// </summary>
/// <param name="context">The context associated with the event to process.</param>
/// <returns>
/// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
/// </returns>
public ValueTask HandleAsync(CustomContext context)
{
return new ValueTask();
}
public ValueTask HandleAsync(CustomContext context) => default;
}
}
}
Loading…
Cancel
Save