diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs
index bc6fc812..291a291c 100644
--- a/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs
@@ -43,7 +43,7 @@ public class HomeController([FromKeyedServices("ApiClient")] HttpClient client,
return View("Index", new IndexViewModel
{
- Message = await response.Content.ReadAsStringAsync(),
+ Message = await response.Content.ReadAsStringAsync(cancellationToken),
Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
index 715be7a3..351874d4 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
@@ -35,7 +35,7 @@ public class HomeController([FromKeyedServices("ApiClient")] HttpClient client,
return View("Index", new IndexViewModel
{
- Message = await response.Content.ReadAsStringAsync(),
+ Message = await response.Content.ReadAsStringAsync(cancellationToken),
Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs
index bff91682..f704f287 100644
--- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs
+++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs
@@ -44,13 +44,23 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler
public async Task HandleRequestAsync()
{
+ // Note: to ensure internal operations are not immediately cancelled when the request is aborted
+ // (which may represent a security risk if sensitive operations are in progress), an ad-hoc token
+ // source is always created and configured to be triggered 5 seconds after the request is aborted.
+ var source = new CancellationTokenSource();
+ var registration = Context.RequestAborted.Register(static state =>
+ ((CancellationTokenSource) state!).CancelAfter(TimeSpan.FromSeconds(5)), source);
+
+ Response.RegisterForDispose(source);
+ Response.RegisterForDispose(registration);
+
// Note: the transaction may be already attached when replaying an ASP.NET Core request
// (e.g when using the built-in status code pages middleware with the re-execute mode).
var transaction = Context.Features.Get()?.Transaction;
if (transaction is null)
{
// Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers.
- transaction = await _factory.CreateTransactionAsync();
+ transaction = await _factory.CreateTransactionAsync(source.Token);
transaction.Properties[typeof(HttpRequest).FullName!] = new WeakReference(Request);
// Attach the OpenIddict client transaction to the ASP.NET Core features
@@ -58,11 +68,7 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler(typeof(ProcessAuthenticationContext).FullName!);
if (context is null)
{
- await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction)
- {
- CancellationToken = Context.RequestAborted
- });
+ await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction));
// 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.
@@ -377,7 +379,6 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler
protected override async Task InitializeCoreAsync()
{
+ // Note: to ensure internal operations are not immediately cancelled when the request is aborted
+ // (which may represent a security risk if sensitive operations are in progress), an ad-hoc token
+ // source is always created and configured to be triggered 5 seconds after the request is aborted.
+ var source = new CancellationTokenSource();
+ var registration = Request.CallCancelled.Register(static state =>
+ ((CancellationTokenSource) state!).CancelAfter(TimeSpan.FromSeconds(5)), source);
+
+ Response.OnSendingHeaders(static state => ((CancellationTokenSource) state!).Dispose(), source);
+ Response.OnSendingHeaders(static state => ((CancellationTokenRegistration) state!).Dispose(), registration);
+
// Note: the transaction may be already attached when replaying an OWIN request
// (e.g when using a status code pages middleware re-invoking the OWIN pipeline).
var transaction = Context.Get(typeof(OpenIddictClientTransaction).FullName);
if (transaction is null)
{
// Create a new transaction and attach the OWIN request to make it available to the OWIN handlers.
- transaction = await _factory.CreateTransactionAsync();
+ transaction = await _factory.CreateTransactionAsync(source.Token);
transaction.Properties[typeof(IOwinRequest).FullName!] = new WeakReference(Request);
// Attach the OpenIddict client transaction to the OWIN shared dictionary
@@ -60,11 +70,7 @@ public sealed class OpenIddictClientOwinHandler : AuthenticationHandler(typeof(ProcessAuthenticationContext).FullName!);
if (context is null)
{
- await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction)
- {
- CancellationToken = Request.CallCancelled
- });
+ await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction));
// 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.
@@ -302,7 +304,6 @@ public sealed class OpenIddictClientOwinHandler : AuthenticationHandler "Authentication failed. Please return to the application."
});
- await response.OutputStream.WriteAsync(buffer);
- await response.OutputStream.FlushAsync();
+ await response.OutputStream.WriteAsync(buffer.AsMemory(), context.CancellationToken);
+ await response.OutputStream.FlushAsync(context.CancellationToken);
context.HandleRequest();
}
diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs
index 1551a2f6..85950f40 100644
--- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs
+++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs
@@ -646,8 +646,8 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
_ => "Logout failed. Please return to the application."
});
- await response.OutputStream.WriteAsync(buffer);
- await response.OutputStream.FlushAsync();
+ await response.OutputStream.WriteAsync(buffer.AsMemory(), context.CancellationToken);
+ await response.OutputStream.FlushAsync(context.CancellationToken);
context.HandleRequest();
}
diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs
index 23fefd7d..138e4bd6 100644
--- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs
+++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs
@@ -457,7 +457,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers
context.Transaction.Request = new OpenIddictRequest(await OpenIddictHelpers.ParseFormAsync(
stream : request.InputStream,
encoding : GetEncoding(type) is { CodePage: not 65000 } encoding ? encoding : Encoding.UTF8,
- cancellationToken: CancellationToken.None));
+ cancellationToken: context.CancellationToken));
}
else
diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs
index a4a8d6a5..ff628085 100644
--- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs
+++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs
@@ -147,21 +147,16 @@ public sealed class OpenIddictClientSystemIntegrationService
// Create a client transaction and store the specified instance so
// it can be retrieved by the event handlers that need to access it.
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
transaction.SetProperty(typeof(TProperty).FullName!, property);
- var context = new ProcessRequestContext(transaction)
- {
- CancellationToken = cancellationToken
- };
-
+ var context = new ProcessRequestContext(transaction);
await dispatcher.DispatchAsync(context);
if (context.IsRejected)
{
await dispatcher.DispatchAsync(new ProcessErrorContext(transaction)
{
- CancellationToken = cancellationToken,
Error = context.Error ?? Errors.InvalidRequest,
ErrorDescription = context.ErrorDescription,
ErrorUri = context.ErrorUri,
diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs
index 41b34fcb..482ea91b 100644
--- a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs
+++ b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Userinfo.cs
@@ -127,7 +127,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
MediaTypes.JsonWebToken, StringComparison.OrdinalIgnoreCase))
{
context.Response = new OpenIddictResponse();
- context.UserInfoToken = await response.Content.ReadAsStringAsync();
+ context.UserInfoToken = await response.Content.ReadAsStringAsync(context.CancellationToken);
return;
}
diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs
index b5036220..8819d0ec 100644
--- a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs
+++ b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs
@@ -611,7 +611,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
else if (string.Equals(encoding, ContentEncodings.Gzip, StringComparison.OrdinalIgnoreCase))
{
- stream ??= await response.Content.ReadAsStreamAsync();
+ stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken);
stream = new GZipStream(stream, CompressionMode.Decompress);
}
@@ -625,13 +625,13 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
// For more information, read https://www.rfc-editor.org/rfc/rfc9110.html#name-deflate-coding.
else if (string.Equals(encoding, ContentEncodings.Deflate, StringComparison.OrdinalIgnoreCase))
{
- stream ??= await response.Content.ReadAsStreamAsync();
+ stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken);
stream = new ZLibStream(stream, CompressionMode.Decompress);
}
else if (string.Equals(encoding, ContentEncodings.Brotli, StringComparison.OrdinalIgnoreCase))
{
- stream ??= await response.Content.ReadAsStreamAsync();
+ stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken);
stream = new BrotliStream(stream, CompressionMode.Decompress);
}
#endif
@@ -655,7 +655,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
// (e.g if the JSON deserialization process fails, the stream is read as a string
// during a second pass a second time for logging/debuggability purposes).
var content = new StreamContent(stream);
- await content.LoadIntoBufferAsync();
+ await content.LoadIntoBufferAsync(context.CancellationToken);
// Copy the headers from the original content to the new instance.
foreach (var header in response.Content.Headers)
@@ -728,7 +728,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
catch (Exception exception) when (!OpenIddictHelpers.IsFatal(exception))
{
context.Logger.LogError(6183, exception, SR.GetResourceString(SR.ID6183),
- await response.Content.ReadAsStringAsync());
+ await response.Content.ReadAsStringAsync(context.CancellationToken));
context.Reject(
error: Errors.ServerError,
@@ -949,7 +949,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
if (!response.IsSuccessStatusCode && string.IsNullOrEmpty(context.Transaction.Response?.Error))
{
context.Logger.LogError(6184, SR.GetResourceString(SR.ID6184), response.StatusCode,
- await response.Content.ReadAsStringAsync());
+ await response.Content.ReadAsStringAsync(context.CancellationToken));
context.Reject(
error: (int) response.StatusCode switch
@@ -973,7 +973,7 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
if (context.Transaction.Response is null)
{
context.Logger.LogError(6185, SR.GetResourceString(SR.ID6185), response.StatusCode,
- response.Content.Headers.ContentType, await response.Content.ReadAsStringAsync());
+ response.Content.Headers.ContentType, await response.Content.ReadAsStringAsync(context.CancellationToken));
context.Reject(
error: Errors.ServerError,
diff --git a/src/OpenIddict.Client/IOpenIddictClientFactory.cs b/src/OpenIddict.Client/IOpenIddictClientFactory.cs
index 24e1dfd2..91713f97 100644
--- a/src/OpenIddict.Client/IOpenIddictClientFactory.cs
+++ b/src/OpenIddict.Client/IOpenIddictClientFactory.cs
@@ -18,9 +18,13 @@ public interface IOpenIddictClientFactory
/// Creates a new that is used as a
/// way to store per-request data needed to process the requested operation.
///
+ /// The that can be used to abort the operation.
+ ///
+ /// Note: the specified is automatically attached to the returned transaction.
+ ///
///
/// A that can be used to monitor the asynchronous
/// operation, whose result returns the created transaction.
///
- ValueTask CreateTransactionAsync();
+ ValueTask CreateTransactionAsync(CancellationToken cancellationToken);
}
diff --git a/src/OpenIddict.Client/OpenIddictClientConfiguration.cs b/src/OpenIddict.Client/OpenIddictClientConfiguration.cs
index 0d5e9a66..a92e7165 100644
--- a/src/OpenIddict.Client/OpenIddictClientConfiguration.cs
+++ b/src/OpenIddict.Client/OpenIddictClientConfiguration.cs
@@ -88,8 +88,8 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions registration.RedirectUri is not null)
- .Select(registration => registration.RedirectUri!)
+ .Where(static registration => registration.RedirectUri is not null)
+ .Select(static registration => registration.RedirectUri!)
.Where(uri => !options.RedirectionEndpointUris.Contains(uri))
.Distinct()
.ToList());
@@ -97,8 +97,8 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions registration.PostLogoutRedirectUri is not null)
- .Select(registration => registration.PostLogoutRedirectUri!)
+ .Where(static registration => registration.PostLogoutRedirectUri is not null)
+ .Select(static registration => registration.PostLogoutRedirectUri!)
.Where(uri => !options.PostLogoutRedirectionEndpointUris.Contains(uri))
.Distinct()
.ToList());
@@ -113,9 +113,9 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions Compare(left.Key, right.Key, now));
// Generate a key identifier for the encryption/signing keys that don't already have one.
- foreach (var key in options.EncryptionCredentials.Select(credentials => credentials.Key)
- .Concat(options.SigningCredentials.Select(credentials => credentials.Key))
- .Where(key => string.IsNullOrEmpty(key.KeyId)))
+ foreach (var key in options.EncryptionCredentials.Select(static credentials => credentials.Key)
+ .Concat(options.SigningCredentials.Select(static credentials => credentials.Key))
+ .Where(static key => string.IsNullOrEmpty(key.KeyId)))
{
key.KeyId = GetKeyIdentifier(key);
}
@@ -354,7 +354,7 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions registration.RegistrationId)
+ if (options.Registrations.Count != options.Registrations.Select(static registration => registration.RegistrationId)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Count())
{
diff --git a/src/OpenIddict.Client/OpenIddictClientDispatcher.cs b/src/OpenIddict.Client/OpenIddictClientDispatcher.cs
index e0373ba6..5e7dae63 100644
--- a/src/OpenIddict.Client/OpenIddictClientDispatcher.cs
+++ b/src/OpenIddict.Client/OpenIddictClientDispatcher.cs
@@ -40,6 +40,8 @@ public sealed class OpenIddictClientDispatcher : IOpenIddictClientDispatcher
await foreach (var handler in GetHandlersAsync())
{
+ context.CancellationToken.ThrowIfCancellationRequested();
+
try
{
await handler.HandleAsync(context);
diff --git a/src/OpenIddict.Client/OpenIddictClientEvents.cs b/src/OpenIddict.Client/OpenIddictClientEvents.cs
index c7cd6d47..4f11e13f 100644
--- a/src/OpenIddict.Client/OpenIddictClientEvents.cs
+++ b/src/OpenIddict.Client/OpenIddictClientEvents.cs
@@ -32,19 +32,9 @@ public static partial class OpenIddictClientEvents
public OpenIddictClientTransaction Transaction { get; }
///
- /// Gets or sets the cancellation token that will be
- /// used to determine if the operation was aborted.
+ /// Gets the cancellation token used to determine if the operation was aborted.
///
- ///
- /// Note: for security reasons, this property shouldn't be used by event
- /// handlers to abort security-sensitive operations. As such, it is
- /// recommended to use this property only for user-dependent operations.
- ///
- public CancellationToken CancellationToken
- {
- get => Transaction.CancellationToken;
- set => Transaction.CancellationToken = value;
- }
+ public CancellationToken CancellationToken => Transaction.CancellationToken;
///
/// Gets or sets the endpoint type that handled the request, if applicable.
diff --git a/src/OpenIddict.Client/OpenIddictClientFactory.cs b/src/OpenIddict.Client/OpenIddictClientFactory.cs
index 59cf992d..1ae7a02f 100644
--- a/src/OpenIddict.Client/OpenIddictClientFactory.cs
+++ b/src/OpenIddict.Client/OpenIddictClientFactory.cs
@@ -31,10 +31,18 @@ public sealed class OpenIddictClientFactory : IOpenIddictClientFactory
}
///
- public ValueTask CreateTransactionAsync()
- => new(new OpenIddictClientTransaction
+ public ValueTask CreateTransactionAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return new(Task.FromCanceled(cancellationToken));
+ }
+
+ return new(new OpenIddictClientTransaction
{
+ CancellationToken = cancellationToken,
Logger = _logger,
Options = _options.CurrentValue
});
+ }
}
diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
index f0396abb..aba7b694 100644
--- a/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
+++ b/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs
@@ -274,7 +274,7 @@ public static partial class OpenIddictClientHandlers
}
// If the reference token cannot be found, don't return an error to allow another handler to validate it.
- var token = await _tokenManager.FindByReferenceIdAsync(context.Token);
+ var token = await _tokenManager.FindByReferenceIdAsync(context.Token, context.CancellationToken);
if (token is null)
{
return;
@@ -284,8 +284,8 @@ public static partial class OpenIddictClientHandlers
if (!(context.ValidTokenTypes.Count switch
{
0 => true, // If no specific token type is expected, accept all token types at this stage.
- 1 => await _tokenManager.HasTypeAsync(token, context.ValidTokenTypes.ElementAt(0)),
- _ => await _tokenManager.HasTypeAsync(token, [.. context.ValidTokenTypes])
+ 1 => await _tokenManager.HasTypeAsync(token, context.ValidTokenTypes.ElementAt(0), context.CancellationToken),
+ _ => await _tokenManager.HasTypeAsync(token, [.. context.ValidTokenTypes], context.CancellationToken)
}))
{
context.Reject(
@@ -296,7 +296,7 @@ public static partial class OpenIddictClientHandlers
return;
}
- var payload = await _tokenManager.GetPayloadAsync(token);
+ var payload = await _tokenManager.GetPayloadAsync(token, context.CancellationToken);
if (string.IsNullOrEmpty(payload))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0026));
@@ -307,7 +307,7 @@ public static partial class OpenIddictClientHandlers
// used to restore the properties associated with the token.
context.IsReferenceToken = true;
context.Token = payload;
- context.TokenId = await _tokenManager.GetIdAsync(token);
+ context.TokenId = await _tokenManager.GetIdAsync(token, context.CancellationToken);
}
}
@@ -575,7 +575,7 @@ public static partial class OpenIddictClientHandlers
}
// If the token entry cannot be found, return a generic error.
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is null)
{
context.Reject(
@@ -589,9 +589,9 @@ public static partial class OpenIddictClientHandlers
// If the token was not validated as a reference token but has a reference identifier attached, this
// may indicate that the payload stored in the database has leaked and is being used as a regular,
// non-reference token. To prevent this, reject the token if the reference identifier is not null.
- if (!context.IsReferenceToken && !string.IsNullOrEmpty(await _tokenManager.GetReferenceIdAsync(token)))
+ if (!context.IsReferenceToken && !string.IsNullOrEmpty(await _tokenManager.GetReferenceIdAsync(token, context.CancellationToken)))
{
- context.Logger.LogWarning(6292, SR.GetResourceString(SR.ID6292), await _tokenManager.GetIdAsync(token));
+ context.Logger.LogWarning(6292, SR.GetResourceString(SR.ID6292), await _tokenManager.GetIdAsync(token, context.CancellationToken));
context.Reject(
error: Errors.InvalidToken,
@@ -603,10 +603,10 @@ public static partial class OpenIddictClientHandlers
// Restore the creation/expiration dates/identifiers from the token entry metadata.
context.Principal
- .SetCreationDate(await _tokenManager.GetCreationDateAsync(token))
- .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token))
- .SetTokenId(context.TokenId = await _tokenManager.GetIdAsync(token))
- .SetTokenType(await _tokenManager.GetTypeAsync(token));
+ .SetCreationDate(await _tokenManager.GetCreationDateAsync(token, context.CancellationToken))
+ .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token, context.CancellationToken))
+ .SetTokenId(context.TokenId = await _tokenManager.GetIdAsync(token, context.CancellationToken))
+ .SetTokenType(await _tokenManager.GetTypeAsync(token, context.CancellationToken));
}
}
@@ -851,10 +851,10 @@ public static partial class OpenIddictClientHandlers
Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.TokenId), SR.GetResourceString(SR.ID4017));
- var token = await _tokenManager.FindByIdAsync(context.TokenId)
+ var token = await _tokenManager.FindByIdAsync(context.TokenId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0021));
- if (await _tokenManager.HasStatusAsync(token, Statuses.Redeemed))
+ if (await _tokenManager.HasStatusAsync(token, Statuses.Redeemed, context.CancellationToken))
{
context.Logger.LogInformation(6002, SR.GetResourceString(SR.ID6002), context.TokenId);
@@ -876,7 +876,7 @@ public static partial class OpenIddictClientHandlers
return;
}
- if (!await _tokenManager.HasStatusAsync(token, Statuses.Valid))
+ if (!await _tokenManager.HasStatusAsync(token, Statuses.Valid, context.CancellationToken))
{
context.Logger.LogInformation(6005, SR.GetResourceString(SR.ID6005), context.TokenId);
@@ -980,10 +980,10 @@ public static partial class OpenIddictClientHandlers
// Tokens produced by the client stack cannot have an application attached.
- var token = await _tokenManager.CreateAsync(descriptor)
+ var token = await _tokenManager.CreateAsync(descriptor, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0019));
- var identifier = await _tokenManager.GetIdAsync(token);
+ var identifier = await _tokenManager.GetIdAsync(token, context.CancellationToken);
// Attach the token identifier to the principal so that it can be stored in the token.
context.Principal.SetTokenId(identifier);
@@ -1172,11 +1172,11 @@ public static partial class OpenIddictClientHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0009));
}
- var token = await _tokenManager.FindByIdAsync(identifier)
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0021));
var descriptor = new OpenIddictTokenDescriptor();
- await _tokenManager.PopulateAsync(descriptor, token);
+ await _tokenManager.PopulateAsync(descriptor, token, context.CancellationToken);
// Attach the generated token to the token entry.
descriptor.Payload = context.Token;
@@ -1187,7 +1187,7 @@ public static partial class OpenIddictClientHandlers
descriptor.ReferenceId = Base64Url.EncodeToString(RandomNumberGenerator.GetBytes(count: 256 / 8));
}
- await _tokenManager.UpdateAsync(token, descriptor);
+ await _tokenManager.UpdateAsync(token, descriptor, context.CancellationToken);
context.Logger.LogTrace(6014, SR.GetResourceString(SR.ID6014), context.Token, identifier, context.TokenType);
diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.cs
index 0acac21c..9fbb27fd 100644
--- a/src/OpenIddict.Client/OpenIddictClientHandlers.cs
+++ b/src/OpenIddict.Client/OpenIddictClientHandlers.cs
@@ -7,7 +7,9 @@
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Buffers.Text;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
@@ -18,8 +20,6 @@ using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using static OpenIddict.Abstractions.OpenIddictExceptions;
-using System.Runtime.CompilerServices;
-using System.Buffers.Text;
#if !NET
using Org.BouncyCastle.Crypto.Digests;
@@ -857,8 +857,8 @@ public static partial class OpenIddictClientHandlers
}
// Mark the token as redeemed to prevent future reuses.
- var token = await _tokenManager.FindByIdAsync(identifier);
- if (token is not null && !await _tokenManager.TryRedeemAsync(token))
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
+ if (token is not null && !await _tokenManager.TryRedeemAsync(token, context.CancellationToken))
{
context.Reject(
error: Errors.InvalidToken,
diff --git a/src/OpenIddict.Client/OpenIddictClientService.cs b/src/OpenIddict.Client/OpenIddictClientService.cs
index 0d04fbfe..34bcb79d 100644
--- a/src/OpenIddict.Client/OpenIddictClientService.cs
+++ b/src/OpenIddict.Client/OpenIddictClientService.cs
@@ -266,11 +266,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
- CancellationToken = request.CancellationToken,
Nonce = request.Nonce,
Request = new(),
TokenEndpointClientCertificate = request.TokenBindingCertificate,
@@ -340,11 +339,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessChallengeContext(transaction)
{
- CancellationToken = request.CancellationToken,
CodeChallengeMethod = request.CodeChallengeMethod,
GrantType = request.GrantType,
IdentityTokenHint = request.IdentityTokenHint,
@@ -422,11 +420,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
- CancellationToken = request.CancellationToken,
GrantType = GrantTypes.ClientCredentials,
Issuer = request.Issuer,
ProviderName = request.ProviderName,
@@ -513,11 +510,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
- CancellationToken = request.CancellationToken,
DisableUserInfoRetrieval = request.DisableUserInfo,
DisableUserInfoValidation = request.DisableUserInfo,
GrantType = request.GrantType,
@@ -607,11 +603,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
- CancellationToken = source.Token,
DeviceCode = request.DeviceCode,
DisableUserInfoRetrieval = request.DisableUserInfo,
DisableUserInfoValidation = request.DisableUserInfo,
@@ -714,11 +709,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessChallengeContext(transaction)
{
- CancellationToken = request.CancellationToken,
DeviceAuthorizationRequest = request.AdditionalDeviceAuthorizationRequestParameters
is Dictionary parameters ? new(parameters) : new(),
GrantType = GrantTypes.DeviceCode,
@@ -793,11 +787,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
- CancellationToken = request.CancellationToken,
DisableUserInfoRetrieval = request.DisableUserInfo,
DisableUserInfoValidation = request.DisableUserInfo,
GrantType = GrantTypes.Password,
@@ -881,13 +874,12 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
ActorToken = request.ActorToken,
ActorTokenType = request.ActorTokenType,
- CancellationToken = request.CancellationToken,
DisableUserInfoRetrieval = request.DisableUserInfo,
DisableUserInfoValidation = request.DisableUserInfo,
GrantType = GrantTypes.TokenExchange,
@@ -969,11 +961,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
- CancellationToken = request.CancellationToken,
DisableUserInfoRetrieval = request.DisableUserInfo,
DisableUserInfoValidation = request.DisableUserInfo,
GrantType = GrantTypes.RefreshToken,
@@ -1055,11 +1046,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessIntrospectionContext(transaction)
{
- CancellationToken = request.CancellationToken,
IntrospectionRequest = request.AdditionalIntrospectionRequestParameters
is Dictionary parameters ? new(parameters) : new(),
Issuer = request.Issuer,
@@ -1115,11 +1105,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessRevocationContext(transaction)
{
- CancellationToken = request.CancellationToken,
Issuer = request.Issuer,
ProviderName = request.ProviderName,
RegistrationId = request.RegistrationId,
@@ -1183,7 +1172,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
var request = new OpenIddictRequest();
request = await PrepareConfigurationRequestAsync();
@@ -1197,7 +1186,6 @@ public class OpenIddictClientService
{
var context = new PrepareConfigurationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request
@@ -1219,7 +1207,6 @@ public class OpenIddictClientService
{
var context = new ApplyConfigurationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request
@@ -1243,7 +1230,6 @@ public class OpenIddictClientService
{
var context = new ExtractConfigurationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request
@@ -1269,7 +1255,6 @@ public class OpenIddictClientService
{
var context = new HandleConfigurationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request,
@@ -1308,11 +1293,10 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(request.CancellationToken);
var context = new ProcessSignOutContext(transaction)
{
- CancellationToken = request.CancellationToken,
IdentityTokenHint = request.IdentityTokenHint,
Issuer = request.Issuer,
LoginHint = request.LoginHint,
@@ -1379,7 +1363,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
var request = new OpenIddictRequest();
request = await PrepareJsonWebKeySetRequestAsync();
@@ -1394,7 +1378,6 @@ public class OpenIddictClientService
{
var context = new PrepareJsonWebKeySetRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request
@@ -1416,7 +1399,6 @@ public class OpenIddictClientService
{
var context = new ApplyJsonWebKeySetRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request
@@ -1440,7 +1422,6 @@ public class OpenIddictClientService
{
var context = new ExtractJsonWebKeySetResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request
@@ -1466,7 +1447,6 @@ public class OpenIddictClientService
{
var context = new HandleJsonWebKeySetResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Registration = registration,
Request = request,
@@ -1521,7 +1501,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PrepareDeviceAuthorizationRequestAsync();
request = await ApplyDeviceAuthorizationRequestAsync();
@@ -1534,7 +1514,6 @@ public class OpenIddictClientService
{
var context = new PrepareDeviceAuthorizationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
ClientAuthenticationMethod = method,
Configuration = configuration,
RemoteUri = uri,
@@ -1559,7 +1538,6 @@ public class OpenIddictClientService
{
var context = new ApplyDeviceAuthorizationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
@@ -1584,7 +1562,6 @@ public class OpenIddictClientService
{
var context = new ExtractDeviceAuthorizationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
@@ -1611,7 +1588,6 @@ public class OpenIddictClientService
{
var context = new HandleDeviceAuthorizationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
@@ -1666,7 +1642,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PrepareIntrospectionRequestAsync();
request = await ApplyIntrospectionRequestAsync();
@@ -1679,7 +1655,6 @@ public class OpenIddictClientService
{
var context = new PrepareIntrospectionRequestContext(transaction)
{
- CancellationToken = cancellationToken,
ClientAuthenticationMethod = method,
Configuration = configuration,
Registration = registration,
@@ -1704,7 +1679,6 @@ public class OpenIddictClientService
{
var context = new ApplyIntrospectionRequestContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -1729,7 +1703,6 @@ public class OpenIddictClientService
{
var context = new ExtractIntrospectionResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -1756,7 +1729,6 @@ public class OpenIddictClientService
{
var context = new HandleIntrospectionResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -1814,7 +1786,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PreparePushedAuthorizationRequestAsync();
request = await ApplyPushedAuthorizationRequestAsync();
@@ -1827,7 +1799,6 @@ public class OpenIddictClientService
{
var context = new PreparePushedAuthorizationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
ClientAuthenticationMethod = method,
RemoteUri = uri,
Configuration = configuration,
@@ -1852,7 +1823,6 @@ public class OpenIddictClientService
{
var context = new ApplyPushedAuthorizationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
@@ -1877,7 +1847,6 @@ public class OpenIddictClientService
{
var context = new ExtractPushedAuthorizationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
@@ -1904,7 +1873,6 @@ public class OpenIddictClientService
{
var context = new HandlePushedAuthorizationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Registration = registration,
@@ -1959,7 +1927,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PrepareRevocationRequestAsync();
request = await ApplyRevocationRequestAsync();
@@ -1972,7 +1940,6 @@ public class OpenIddictClientService
{
var context = new PrepareRevocationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
ClientAuthenticationMethod = method,
Configuration = configuration,
Registration = registration,
@@ -1997,7 +1964,6 @@ public class OpenIddictClientService
{
var context = new ApplyRevocationRequestContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -2022,7 +1988,6 @@ public class OpenIddictClientService
{
var context = new ExtractRevocationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -2049,7 +2014,6 @@ public class OpenIddictClientService
{
var context = new HandleRevocationResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -2105,7 +2069,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PrepareTokenRequestAsync();
request = await ApplyTokenRequestAsync();
@@ -2118,7 +2082,6 @@ public class OpenIddictClientService
{
var context = new PrepareTokenRequestContext(transaction)
{
- CancellationToken = cancellationToken,
ClientAuthenticationMethod = method,
Configuration = configuration,
Registration = registration,
@@ -2143,7 +2106,6 @@ public class OpenIddictClientService
{
var context = new ApplyTokenRequestContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -2169,7 +2131,6 @@ public class OpenIddictClientService
{
var context = new ExtractTokenResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -2197,7 +2158,6 @@ public class OpenIddictClientService
{
var context = new HandleTokenResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
@@ -2252,7 +2212,7 @@ public class OpenIddictClientService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PrepareUserInfoRequestAsync();
request = await ApplyUserInfoRequestAsync();
@@ -2265,7 +2225,6 @@ public class OpenIddictClientService
{
var context = new PrepareUserInfoRequestContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
RemoteUri = uri,
Registration = registration,
@@ -2289,7 +2248,6 @@ public class OpenIddictClientService
{
var context = new ApplyUserInfoRequestContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
RemoteUri = uri,
Registration = registration,
@@ -2314,7 +2272,6 @@ public class OpenIddictClientService
{
var context = new ExtractUserInfoResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
RemoteUri = uri,
Registration = registration,
@@ -2341,7 +2298,6 @@ public class OpenIddictClientService
{
var context = new HandleUserInfoResponseContext(transaction)
{
- CancellationToken = cancellationToken,
Configuration = configuration,
Registration = registration,
RemoteUri = uri,
diff --git a/src/OpenIddict.Client/OpenIddictClientTransaction.cs b/src/OpenIddict.Client/OpenIddictClientTransaction.cs
index cdc15db4..88a46d20 100644
--- a/src/OpenIddict.Client/OpenIddictClientTransaction.cs
+++ b/src/OpenIddict.Client/OpenIddictClientTransaction.cs
@@ -16,14 +16,8 @@ namespace OpenIddict.Client;
public sealed class OpenIddictClientTransaction
{
///
- /// Gets or sets the cancellation token that will be
- /// used to determine if the operation was aborted.
+ /// Gets or sets the cancellation token used to determine if the operation was aborted.
///
- ///
- /// Note: for security reasons, this property shouldn't be used by event
- /// handlers to abort security-sensitive operations. As such, it is
- /// recommended to use this property only for user-dependent operations.
- ///
public CancellationToken CancellationToken { get; set; }
///
diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
index 15cc58aa..ef08d9f7 100644
--- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
+++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs
@@ -44,13 +44,23 @@ public sealed class OpenIddictServerAspNetCoreHandler : AuthenticationHandler
public async Task HandleRequestAsync()
{
+ // Note: to ensure internal operations are not immediately cancelled when the request is aborted
+ // (which may represent a security risk if sensitive operations are in progress), an ad-hoc token
+ // source is always created and configured to be triggered 5 seconds after the request is aborted.
+ var source = new CancellationTokenSource();
+ var registration = Context.RequestAborted.Register(static state =>
+ ((CancellationTokenSource) state!).CancelAfter(TimeSpan.FromSeconds(5)), source);
+
+ Response.RegisterForDispose(source);
+ Response.RegisterForDispose(registration);
+
// Note: the transaction may be already attached when replaying an ASP.NET Core request
// (e.g when using the built-in status code pages middleware with the re-execute mode).
var transaction = Context.Features.Get()?.Transaction;
if (transaction is null)
{
// Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers.
- transaction = await _factory.CreateTransactionAsync();
+ transaction = await _factory.CreateTransactionAsync(source.Token);
transaction.Properties[typeof(HttpRequest).FullName!] = new WeakReference(Request);
// Attach the OpenIddict server transaction to the ASP.NET Core features
@@ -58,11 +68,7 @@ public sealed class OpenIddictServerAspNetCoreHandler : AuthenticationHandler(typeof(ProcessAuthenticationContext).FullName!);
if (context is null)
{
- await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction)
- {
- CancellationToken = Context.RequestAborted
- });
+ await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction));
// 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.
@@ -393,7 +395,6 @@ public sealed class OpenIddictServerAspNetCoreHandler : AuthenticationHandler
protected override async Task InitializeCoreAsync()
{
+ // Note: to ensure internal operations are not immediately cancelled when the request is aborted
+ // (which may represent a security risk if sensitive operations are in progress), an ad-hoc token
+ // source is always created and configured to be triggered 5 seconds after the request is aborted.
+ var source = new CancellationTokenSource();
+ var registration = Request.CallCancelled.Register(static state =>
+ ((CancellationTokenSource) state!).CancelAfter(TimeSpan.FromSeconds(5)), source);
+
+ Response.OnSendingHeaders(static state => ((CancellationTokenSource) state!).Dispose(), source);
+ Response.OnSendingHeaders(static state => ((CancellationTokenRegistration) state!).Dispose(), registration);
+
// Note: the transaction may be already attached when replaying an OWIN request
// (e.g when using a status code pages middleware re-invoking the OWIN pipeline).
var transaction = Context.Get(typeof(OpenIddictServerTransaction).FullName);
if (transaction is null)
{
// Create a new transaction and attach the OWIN request to make it available to the OWIN handlers.
- transaction = await _factory.CreateTransactionAsync();
+ transaction = await _factory.CreateTransactionAsync(source.Token);
transaction.Properties[typeof(IOwinRequest).FullName!] = new WeakReference(Request);
// Attach the OpenIddict server transaction to the OWIN shared dictionary
@@ -51,11 +61,7 @@ public sealed class OpenIddictServerOwinHandler : AuthenticationHandler(typeof(ProcessAuthenticationContext).FullName!);
if (context is null)
{
- await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction)
- {
- CancellationToken = Request.CallCancelled
- });
+ await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction));
// 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.
@@ -290,7 +292,6 @@ public sealed class OpenIddictServerOwinHandler : AuthenticationHandler GetClientCertificateAsync(IOwinContext context)
+ static async ValueTask GetClientCertificateAsync(
+ IOwinContext context, CancellationToken cancellationToken)
{
// If a loading function was provided by the OWIN host, always invoke it before trying
// to resolve the certificate to ensure it is present in the environment dictionary.
if (context.Get>("ssl.LoadClientCertAsync") is Func loader)
{
- await loader();
+ await loader().WaitAsync(cancellationToken);
}
return context.Get("ssl.ClientCertificate") is X509Certificate certificate
diff --git a/src/OpenIddict.Server/IOpenIddictServerFactory.cs b/src/OpenIddict.Server/IOpenIddictServerFactory.cs
index 40fb02d3..695333d1 100644
--- a/src/OpenIddict.Server/IOpenIddictServerFactory.cs
+++ b/src/OpenIddict.Server/IOpenIddictServerFactory.cs
@@ -18,9 +18,13 @@ public interface IOpenIddictServerFactory
/// Creates a new that is used as a
/// way to store per-request data needed to process the requested operation.
///
+ /// The that can be used to abort the operation.
+ ///
+ /// Note: the specified is automatically attached to the returned transaction.
+ ///
///
/// A that can be used to monitor the asynchronous
/// operation, whose result returns the created transaction.
///
- ValueTask CreateTransactionAsync();
+ ValueTask CreateTransactionAsync(CancellationToken cancellationToken);
}
diff --git a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs
index 4930ac04..9d97f42a 100644
--- a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs
+++ b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs
@@ -77,9 +77,9 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions Compare(left.Key, right.Key, now));
// Generate a key identifier for the encryption/signing keys that don't already have one.
- foreach (var key in options.EncryptionCredentials.Select(credentials => credentials.Key)
- .Concat(options.SigningCredentials.Select(credentials => credentials.Key))
- .Where(key => string.IsNullOrEmpty(key.KeyId)))
+ foreach (var key in options.EncryptionCredentials.Select(static credentials => credentials.Key)
+ .Concat(options.SigningCredentials.Select(static credentials => credentials.Key))
+ .Where(static key => string.IsNullOrEmpty(key.KeyId)))
{
key.KeyId = GetKeyIdentifier(key);
}
diff --git a/src/OpenIddict.Server/OpenIddictServerDispatcher.cs b/src/OpenIddict.Server/OpenIddictServerDispatcher.cs
index c68f3b19..6edc5576 100644
--- a/src/OpenIddict.Server/OpenIddictServerDispatcher.cs
+++ b/src/OpenIddict.Server/OpenIddictServerDispatcher.cs
@@ -40,6 +40,8 @@ public sealed class OpenIddictServerDispatcher : IOpenIddictServerDispatcher
await foreach (var handler in GetHandlersAsync())
{
+ context.CancellationToken.ThrowIfCancellationRequested();
+
try
{
await handler.HandleAsync(context);
diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.cs b/src/OpenIddict.Server/OpenIddictServerEvents.cs
index 65b12246..dce4f282 100644
--- a/src/OpenIddict.Server/OpenIddictServerEvents.cs
+++ b/src/OpenIddict.Server/OpenIddictServerEvents.cs
@@ -30,19 +30,9 @@ public static partial class OpenIddictServerEvents
public OpenIddictServerTransaction Transaction { get; }
///
- /// Gets or sets the cancellation token that will be
- /// used to determine if the operation was aborted.
+ /// Gets the cancellation token used to determine if the operation was aborted.
///
- ///
- /// Note: for security reasons, this property shouldn't be used by event
- /// handlers to abort security-sensitive operations. As such, it is
- /// recommended to use this property only for user-dependent operations.
- ///
- public CancellationToken CancellationToken
- {
- get => Transaction.CancellationToken;
- set => Transaction.CancellationToken = value;
- }
+ public CancellationToken CancellationToken => Transaction.CancellationToken;
///
/// Gets or sets the endpoint type that handled the request, if applicable.
diff --git a/src/OpenIddict.Server/OpenIddictServerFactory.cs b/src/OpenIddict.Server/OpenIddictServerFactory.cs
index df714124..7c0394f6 100644
--- a/src/OpenIddict.Server/OpenIddictServerFactory.cs
+++ b/src/OpenIddict.Server/OpenIddictServerFactory.cs
@@ -31,10 +31,18 @@ public sealed class OpenIddictServerFactory : IOpenIddictServerFactory
}
///
- public ValueTask CreateTransactionAsync()
- => new(new OpenIddictServerTransaction
+ public ValueTask CreateTransactionAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return new(Task.FromCanceled(cancellationToken));
+ }
+
+ return new(new OpenIddictServerTransaction
{
+ CancellationToken = cancellationToken,
Logger = _logger,
Options = _options.CurrentValue
});
+ }
}
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
index d53813f7..5231b99f 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
@@ -1396,14 +1396,14 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// To prevent downgrade attacks, ensure that authorization requests returning
// an access token directly from the authorization endpoint are rejected if
// the client_id corresponds to a confidential application.
if (context.Request.HasResponseType(ResponseTypes.Token) &&
- await _applicationManager.HasClientTypeAsync(application, ClientTypes.Confidential))
+ await _applicationManager.HasClientTypeAsync(application, ClientTypes.Confidential, context.CancellationToken))
{
context.Logger.LogInformation(6045, SR.GetResourceString(SR.ID6045), context.ClientId);
@@ -1449,14 +1449,14 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// If no explicit redirect_uri was specified, retrieve the URI associated with the
// client and ensure exactly one redirect_uri was attached to the client definition.
if (string.IsNullOrEmpty(context.RedirectUri))
{
- var uris = await _applicationManager.GetRedirectUrisAsync(application);
+ var uris = await _applicationManager.GetRedirectUrisAsync(application, context.CancellationToken);
if (uris.Length is not 1)
{
context.Logger.LogInformation(6033, SR.GetResourceString(SR.ID6033), Parameters.RedirectUri);
@@ -1475,7 +1475,7 @@ public static partial class OpenIddictServerHandlers
}
// Otherwise, ensure that the specified redirect_uri is valid and is associated with the client application.
- if (!await _applicationManager.ValidateRedirectUriAsync(application, context.RedirectUri))
+ if (!await _applicationManager.ValidateRedirectUriAsync(application, context.RedirectUri, context.CancellationToken))
{
context.Logger.LogInformation(6046, SR.GetResourceString(SR.ID6046), context.RedirectUri);
@@ -1540,9 +1540,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes]))
+ await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes], context.CancellationToken))
{
- var name = await _scopeManager.GetNameAsync(scope);
+ var name = await _scopeManager.GetNameAsync(scope, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
@@ -1615,9 +1615,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var resource in _resourceManager.FindByNamesAsync([.. resources]))
+ await foreach (var resource in _resourceManager.FindByNamesAsync([.. resources], context.CancellationToken))
{
- var name = await _resourceManager.GetNameAsync(resource);
+ var name = await _resourceManager.GetNameAsync(resource, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
resources.Remove(name);
@@ -1672,11 +1672,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the authorization endpoint.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Authorization))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Authorization, context.CancellationToken))
{
context.Logger.LogInformation(6048, SR.GetResourceString(SR.ID6048), context.ClientId);
@@ -1722,12 +1722,12 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the authorization code grant.
if (context.Request.IsAuthorizationCodeFlow() &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode, context.CancellationToken))
{
context.Logger.LogInformation(6049, SR.GetResourceString(SR.ID6049), context.ClientId);
@@ -1741,7 +1741,7 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the application is not allowed to use the implicit grant.
if (context.Request.IsImplicitFlow() &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit, context.CancellationToken))
{
context.Logger.LogInformation(6050, SR.GetResourceString(SR.ID6050), context.ClientId);
@@ -1755,8 +1755,8 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the application is not allowed to use the authorization code/implicit grants.
if (context.Request.IsHybridFlow() &&
- (!await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode) ||
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit)))
+ (!await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode, context.CancellationToken) ||
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit, context.CancellationToken)))
{
context.Logger.LogInformation(6051, SR.GetResourceString(SR.ID6051), context.ClientId);
@@ -1771,7 +1771,7 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the offline_access scope was request and
// if the application is not allowed to use the refresh token grant.
if (context.Request.HasScope(Scopes.OfflineAccess) &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken, context.CancellationToken))
{
context.Logger.LogInformation(6052, SR.GetResourceString(SR.ID6052), context.ClientId, Scopes.OfflineAccess);
@@ -1817,7 +1817,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject requests that specify a response_type for which no permission was granted.
@@ -1838,7 +1838,7 @@ public static partial class OpenIddictServerHandlers
// Note: response type permissions are always prefixed with "rst:".
const string prefix = Permissions.Prefixes.ResponseType;
- foreach (var permission in await _applicationManager.GetPermissionsAsync(application))
+ foreach (var permission in await _applicationManager.GetPermissionsAsync(application, context.CancellationToken))
{
// Ignore permissions that are not response type permissions.
if (!permission.StartsWith(prefix, StringComparison.Ordinal))
@@ -1892,7 +1892,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var scope in context.Request.GetScopes())
@@ -1905,7 +1905,7 @@ public static partial class OpenIddictServerHandlers
}
// Reject the request if the application is not allowed to use the iterated scope.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope, context.CancellationToken))
{
context.Logger.LogInformation(6052, SR.GetResourceString(SR.ID6052), context.ClientId, scope);
@@ -1953,13 +1953,13 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var resource in context.Request.GetResources())
{
// Reject the request if the application is not allowed to use the iterated resource.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Resource + resource))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Resource + resource, context.CancellationToken))
{
context.Logger.LogInformation(6281, SR.GetResourceString(SR.ID6278), context.ClientId, resource);
@@ -2014,10 +2014,10 @@ public static partial class OpenIddictServerHandlers
return;
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
- if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.PushedAuthorizationRequests))
+ if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.PushedAuthorizationRequests, context.CancellationToken))
{
if (string.IsNullOrEmpty(context.Request.RequestUri))
{
@@ -2080,10 +2080,10 @@ public static partial class OpenIddictServerHandlers
return;
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
- if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.ProofKeyForCodeExchange))
+ if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.ProofKeyForCodeExchange, context.CancellationToken))
{
context.Logger.LogInformation(6033, SR.GetResourceString(SR.ID6033), Parameters.CodeChallenge);
@@ -3483,14 +3483,14 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// To prevent downgrade attacks, ensure that pushed authorization requests returning
// an access token directly from the authorization endpoint are rejected if
// the client_id corresponds to a confidential application.
if (context.Request.HasResponseType(ResponseTypes.Token) &&
- await _applicationManager.HasClientTypeAsync(application, ClientTypes.Confidential))
+ await _applicationManager.HasClientTypeAsync(application, ClientTypes.Confidential, context.CancellationToken))
{
context.Logger.LogInformation(6251, SR.GetResourceString(SR.ID6251), context.ClientId);
@@ -3536,14 +3536,14 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// If no explicit redirect_uri was specified, retrieve the URI associated with the
// client and ensure exactly one redirect_uri was attached to the client definition.
if (string.IsNullOrEmpty(context.RedirectUri))
{
- var uris = await _applicationManager.GetRedirectUrisAsync(application);
+ var uris = await _applicationManager.GetRedirectUrisAsync(application, context.CancellationToken);
if (uris.Length is not 1)
{
context.Logger.LogInformation(6240, SR.GetResourceString(SR.ID6240), Parameters.RedirectUri);
@@ -3562,7 +3562,7 @@ public static partial class OpenIddictServerHandlers
}
// Otherwise, ensure that the specified redirect_uri is valid and is associated with the client application.
- if (!await _applicationManager.ValidateRedirectUriAsync(application, context.RedirectUri))
+ if (!await _applicationManager.ValidateRedirectUriAsync(application, context.RedirectUri, context.CancellationToken))
{
context.Logger.LogInformation(6252, SR.GetResourceString(SR.ID6252), context.RedirectUri);
@@ -3627,9 +3627,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes]))
+ await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes], context.CancellationToken))
{
- var name = await _scopeManager.GetNameAsync(scope);
+ var name = await _scopeManager.GetNameAsync(scope, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
@@ -3702,9 +3702,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var resource in _resourceManager.FindByNamesAsync([.. resources]))
+ await foreach (var resource in _resourceManager.FindByNamesAsync([.. resources], context.CancellationToken))
{
- var name = await _resourceManager.GetNameAsync(resource);
+ var name = await _resourceManager.GetNameAsync(resource, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
resources.Remove(name);
@@ -3759,11 +3759,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the pushed authorization endpoint.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.PushedAuthorization))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.PushedAuthorization, context.CancellationToken))
{
context.Logger.LogInformation(6254, SR.GetResourceString(SR.ID6254), context.ClientId);
@@ -3809,12 +3809,12 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the authorization code grant.
if (context.Request.IsAuthorizationCodeFlow() &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode, context.CancellationToken))
{
context.Logger.LogInformation(6255, SR.GetResourceString(SR.ID6255), context.ClientId);
@@ -3828,7 +3828,7 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the application is not allowed to use the implicit grant.
if (context.Request.IsImplicitFlow() &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit, context.CancellationToken))
{
context.Logger.LogInformation(6256, SR.GetResourceString(SR.ID6256), context.ClientId);
@@ -3842,8 +3842,8 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the application is not allowed to use the authorization code/implicit grants.
if (context.Request.IsHybridFlow() &&
- (!await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode) ||
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit)))
+ (!await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.AuthorizationCode, context.CancellationToken) ||
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.Implicit, context.CancellationToken)))
{
context.Logger.LogInformation(6257, SR.GetResourceString(SR.ID6257), context.ClientId);
@@ -3858,7 +3858,7 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the offline_access scope was request and
// if the application is not allowed to use the refresh token grant.
if (context.Request.HasScope(Scopes.OfflineAccess) &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken, context.CancellationToken))
{
context.Logger.LogInformation(6258, SR.GetResourceString(SR.ID6258), context.ClientId, Scopes.OfflineAccess);
@@ -3904,7 +3904,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject requests that specify a response_type for which no permission was granted.
@@ -3925,7 +3925,7 @@ public static partial class OpenIddictServerHandlers
// Note: response type permissions are always prefixed with "rst:".
const string prefix = Permissions.Prefixes.ResponseType;
- foreach (var permission in await _applicationManager.GetPermissionsAsync(application))
+ foreach (var permission in await _applicationManager.GetPermissionsAsync(application, context.CancellationToken))
{
// Ignore permissions that are not response type permissions.
if (!permission.StartsWith(prefix, StringComparison.Ordinal))
@@ -3979,7 +3979,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var scope in context.Request.GetScopes())
@@ -3992,7 +3992,7 @@ public static partial class OpenIddictServerHandlers
}
// Reject the request if the application is not allowed to use the iterated scope.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope, context.CancellationToken))
{
context.Logger.LogInformation(6258, SR.GetResourceString(SR.ID6258), context.ClientId, scope);
@@ -4040,13 +4040,13 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var resource in context.Request.GetResources())
{
// Reject the request if the application is not allowed to use the iterated resource.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Resource + resource))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Resource + resource, context.CancellationToken))
{
context.Logger.LogInformation(6283, SR.GetResourceString(SR.ID6279), context.ClientId, resource);
@@ -4100,10 +4100,10 @@ public static partial class OpenIddictServerHandlers
return;
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
- if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.ProofKeyForCodeExchange))
+ if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.ProofKeyForCodeExchange, context.CancellationToken))
{
context.Logger.LogInformation(6240, SR.GetResourceString(SR.ID6240), Parameters.CodeChallenge);
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
index 92bf129a..ca052ea4 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
@@ -481,9 +481,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes]))
+ await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes], context.CancellationToken))
{
- var name = await _scopeManager.GetNameAsync(scope);
+ var name = await _scopeManager.GetNameAsync(scope, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
@@ -595,14 +595,14 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the device authorization endpoint.
//
// Note: the legacy "ept:device" permission is still allowed for backward compatibility.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.DeviceAuthorization) &&
- !await _applicationManager.HasPermissionAsync(application, "ept:device"))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.DeviceAuthorization, context.CancellationToken) &&
+ !await _applicationManager.HasPermissionAsync(application, "ept:device", context.CancellationToken))
{
context.Logger.LogInformation(6062, SR.GetResourceString(SR.ID6062), context.ClientId);
@@ -648,11 +648,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the device code grant.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.DeviceCode))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.DeviceCode, context.CancellationToken))
{
context.Logger.LogInformation(6118, SR.GetResourceString(SR.ID6118), context.ClientId);
@@ -667,7 +667,7 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the offline_access scope was request and
// if the application is not allowed to use the refresh token grant.
if (context.Request.HasScope(Scopes.OfflineAccess) &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken, context.CancellationToken))
{
context.Logger.LogInformation(6120, SR.GetResourceString(SR.ID6120), context.ClientId, Scopes.OfflineAccess);
@@ -715,7 +715,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var scope in context.Request.GetScopes())
@@ -728,7 +728,7 @@ public static partial class OpenIddictServerHandlers
}
// Reject the request if the application is not allowed to use the iterated scope.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope, context.CancellationToken))
{
context.Logger.LogInformation(6063, SR.GetResourceString(SR.ID6063), context.ClientId, scope);
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
index 95bff8d6..6d22cf52 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
@@ -1047,9 +1047,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes]))
+ await foreach (var scope in _scopeManager.FindByNamesAsync([.. scopes], context.CancellationToken))
{
- var name = await _scopeManager.GetNameAsync(scope);
+ var name = await _scopeManager.GetNameAsync(scope, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
scopes.Remove(name);
@@ -1163,9 +1163,9 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- await foreach (var resource in _resourceManager.FindByNamesAsync([.. resources]))
+ await foreach (var resource in _resourceManager.FindByNamesAsync([.. resources], context.CancellationToken))
{
- var name = await _resourceManager.GetNameAsync(resource);
+ var name = await _resourceManager.GetNameAsync(resource, context.CancellationToken);
if (!string.IsNullOrEmpty(name))
{
resources.Remove(name);
@@ -1284,11 +1284,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the token endpoint.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Token))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Token, context.CancellationToken))
{
context.Logger.LogInformation(6086, SR.GetResourceString(SR.ID6086), context.ClientId);
@@ -1336,11 +1336,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the specified grant type.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.GrantType + context.Request.GrantType))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.GrantType + context.Request.GrantType, context.CancellationToken))
{
context.Logger.LogInformation(6087, SR.GetResourceString(SR.ID6087), context.ClientId, context.Request.GrantType);
@@ -1355,7 +1355,7 @@ public static partial class OpenIddictServerHandlers
// Reject the request if the offline_access scope was request and if
// the application is not allowed to use the refresh token grant type.
if (context.Request.HasScope(Scopes.OfflineAccess) &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.GrantTypes.RefreshToken, context.CancellationToken))
{
context.Logger.LogInformation(6088, SR.GetResourceString(SR.ID6088), context.ClientId, Scopes.OfflineAccess);
@@ -1403,7 +1403,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var scope in context.Request.GetScopes())
@@ -1416,7 +1416,7 @@ public static partial class OpenIddictServerHandlers
}
// Reject the request if the application is not allowed to use the iterated scope.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Scope + scope, context.CancellationToken))
{
context.Logger.LogInformation(6089, SR.GetResourceString(SR.ID6089), context.ClientId, scope);
@@ -1465,13 +1465,13 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var audience in context.Request.GetAudiences())
{
// Reject the request if the application is not allowed to use the iterated audience.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Audience + audience))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Audience + audience, context.CancellationToken))
{
context.Logger.LogInformation(6278, SR.GetResourceString(SR.ID6276), context.ClientId, audience);
@@ -1520,13 +1520,13 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
foreach (var resource in context.Request.GetResources())
{
// Reject the request if the application is not allowed to use the iterated resource.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Resource + resource))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Prefixes.Resource + resource, context.CancellationToken))
{
context.Logger.LogInformation(6279, SR.GetResourceString(SR.ID6277), context.ClientId, resource);
@@ -1586,10 +1586,10 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
- if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.ProofKeyForCodeExchange))
+ if (await _applicationManager.HasRequirementAsync(application, Requirements.Features.ProofKeyForCodeExchange, context.CancellationToken))
{
context.Logger.LogInformation(6077, SR.GetResourceString(SR.ID6077), Parameters.CodeVerifier);
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
index f96c8396..51f1eac2 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
@@ -528,11 +528,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the introspection endpoint.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Introspection))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Introspection, context.CancellationToken))
{
context.Logger.LogInformation(6103, SR.GetResourceString(SR.ID6103), context.ClientId);
@@ -816,11 +816,11 @@ public static partial class OpenIddictServerHandlers
return;
}
- var application = await _applicationManager.FindByClientIdAsync(context.Request.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.Request.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Public clients are not allowed to access sensitive claims as authentication cannot be enforced.
- if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
+ if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public, context.CancellationToken))
{
context.Logger.LogInformation(6107, SR.GetResourceString(SR.ID6107), context.Request.ClientId);
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs
index 0a24d124..dbbc0a8f 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs
@@ -173,8 +173,8 @@ public static partial class OpenIddictServerHandlers
// the signing keys from the JSON Web Key set attached to the client application.
//
// Important: at this stage, the issuer isn't guaranteed to be valid or legitimate.
- var application = await _applicationManager.FindByClientIdAsync(token.Issuer);
- if (application is not null && await _applicationManager.GetJsonWebKeySetAsync(application)
+ var application = await _applicationManager.FindByClientIdAsync(token.Issuer, context.CancellationToken);
+ if (application is not null && await _applicationManager.GetJsonWebKeySetAsync(application, context.CancellationToken)
is JsonWebKeySet set)
{
return set.GetSigningKeys();
@@ -359,7 +359,7 @@ public static partial class OpenIddictServerHandlers
}
// If the reference token cannot be found, don't return an error to allow another handler to validate it.
- var token = await _tokenManager.FindByReferenceIdAsync(context.Token);
+ var token = await _tokenManager.FindByReferenceIdAsync(context.Token, context.CancellationToken);
if (token is null)
{
return;
@@ -369,8 +369,8 @@ public static partial class OpenIddictServerHandlers
if (!(context.ValidTokenTypes.Count switch
{
0 => true, // If no specific token type is expected, accept all token types at this stage.
- 1 => await _tokenManager.HasTypeAsync(token, context.ValidTokenTypes.ElementAt(0)),
- _ => await _tokenManager.HasTypeAsync(token, [.. context.ValidTokenTypes])
+ 1 => await _tokenManager.HasTypeAsync(token, context.ValidTokenTypes.ElementAt(0), context.CancellationToken),
+ _ => await _tokenManager.HasTypeAsync(token, [.. context.ValidTokenTypes], context.CancellationToken)
}))
{
context.Reject(
@@ -407,7 +407,7 @@ public static partial class OpenIddictServerHandlers
return;
}
- var payload = await _tokenManager.GetPayloadAsync(token);
+ var payload = await _tokenManager.GetPayloadAsync(token, context.CancellationToken);
if (string.IsNullOrEmpty(payload))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0026));
@@ -418,7 +418,7 @@ public static partial class OpenIddictServerHandlers
// used to restore the properties associated with the token.
context.IsReferenceToken = true;
context.Token = payload;
- context.TokenId = await _tokenManager.GetIdAsync(token);
+ context.TokenId = await _tokenManager.GetIdAsync(token, context.CancellationToken);
}
}
@@ -799,7 +799,7 @@ public static partial class OpenIddictServerHandlers
}
// If the token entry cannot be found, return a generic error.
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is null)
{
context.Reject(
@@ -827,9 +827,9 @@ public static partial class OpenIddictServerHandlers
// If the token was not validated as a reference token but has a reference identifier attached, this
// may indicate that the payload stored in the database has leaked and is being used as a regular,
// non-reference token. To prevent this, reject the token if the reference identifier is not null.
- if (!context.IsReferenceToken && !string.IsNullOrEmpty(await _tokenManager.GetReferenceIdAsync(token)))
+ if (!context.IsReferenceToken && !string.IsNullOrEmpty(await _tokenManager.GetReferenceIdAsync(token, context.CancellationToken)))
{
- context.Logger.LogWarning(6292, SR.GetResourceString(SR.ID6292), await _tokenManager.GetIdAsync(token));
+ context.Logger.LogWarning(6292, SR.GetResourceString(SR.ID6292), await _tokenManager.GetIdAsync(token, context.CancellationToken));
context.Reject(
error: Errors.InvalidToken,
@@ -855,11 +855,11 @@ public static partial class OpenIddictServerHandlers
// Restore the creation/expiration dates/identifiers from the token entry metadata.
context.Principal
- .SetCreationDate(await _tokenManager.GetCreationDateAsync(token))
- .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token))
- .SetAuthorizationId(context.AuthorizationId = await _tokenManager.GetAuthorizationIdAsync(token))
- .SetTokenId(context.TokenId = await _tokenManager.GetIdAsync(token))
- .SetTokenType(await _tokenManager.GetTypeAsync(token));
+ .SetCreationDate(await _tokenManager.GetCreationDateAsync(token, context.CancellationToken))
+ .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token, context.CancellationToken))
+ .SetAuthorizationId(context.AuthorizationId = await _tokenManager.GetAuthorizationIdAsync(token, context.CancellationToken))
+ .SetTokenId(context.TokenId = await _tokenManager.GetIdAsync(token, context.CancellationToken))
+ .SetTokenType(await _tokenManager.GetTypeAsync(token, context.CancellationToken));
}
}
@@ -1236,7 +1236,7 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.TokenId), SR.GetResourceString(SR.ID4017));
- var token = await _tokenManager.FindByIdAsync(context.TokenId)
+ var token = await _tokenManager.FindByIdAsync(context.TokenId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0021));
// If the token is already marked as redeemed, this may indicate that it was compromised.
@@ -1245,7 +1245,7 @@ public static partial class OpenIddictServerHandlers
// Special logic is used to avoid revoking refresh tokens already marked as redeemed to allow for a small leeway.
// Note: the authorization itself is not revoked to allow the legitimate client to start a new flow.
// See https://tools.ietf.org/html/rfc6749#section-10.5 for more information.
- if (await _tokenManager.HasStatusAsync(token, Statuses.Redeemed))
+ if (await _tokenManager.HasStatusAsync(token, Statuses.Redeemed, context.CancellationToken))
{
if (!context.Principal.HasTokenType(TokenTypeIdentifiers.RefreshToken) || !await IsReusableAsync(token))
{
@@ -1255,7 +1255,7 @@ public static partial class OpenIddictServerHandlers
try
{
- count = await _tokenManager.RevokeByAuthorizationIdAsync(context.AuthorizationId);
+ count = await _tokenManager.RevokeByAuthorizationIdAsync(context.AuthorizationId, context.CancellationToken);
}
catch (Exception exception) when (!OpenIddictHelpers.IsFatal(exception))
@@ -1302,7 +1302,7 @@ public static partial class OpenIddictServerHandlers
}
// If the token is not marked as valid yet, return an authorization_pending error.
- if (await _tokenManager.HasStatusAsync(token, Statuses.Inactive))
+ if (await _tokenManager.HasStatusAsync(token, Statuses.Inactive, context.CancellationToken))
{
context.Logger.LogInformation(6003, SR.GetResourceString(SR.ID6003), context.TokenId);
@@ -1315,7 +1315,7 @@ public static partial class OpenIddictServerHandlers
}
// If the token is marked as rejected, return an access_denied error.
- if (await _tokenManager.HasStatusAsync(token, Statuses.Rejected))
+ if (await _tokenManager.HasStatusAsync(token, Statuses.Rejected, context.CancellationToken))
{
context.Logger.LogInformation(6004, SR.GetResourceString(SR.ID6004), context.TokenId);
@@ -1327,7 +1327,7 @@ public static partial class OpenIddictServerHandlers
return;
}
- if (!await _tokenManager.HasStatusAsync(token, Statuses.Valid))
+ if (!await _tokenManager.HasStatusAsync(token, Statuses.Valid, context.CancellationToken))
{
context.Logger.LogInformation(6005, SR.GetResourceString(SR.ID6005), context.TokenId);
@@ -1367,7 +1367,7 @@ public static partial class OpenIddictServerHandlers
return false;
}
- var date = await _tokenManager.GetRedemptionDateAsync(token);
+ var date = await _tokenManager.GetRedemptionDateAsync(token, context.CancellationToken);
if (date is null || context.Options.TimeProvider.GetUtcNow() <
date + context.Options.RefreshTokenReuseLeeway)
{
@@ -1413,8 +1413,8 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.AuthorizationId), SR.GetResourceString(SR.ID4018));
- var authorization = await _authorizationManager.FindByIdAsync(context.AuthorizationId);
- if (authorization is null || !await _authorizationManager.HasStatusAsync(authorization, Statuses.Valid))
+ var authorization = await _authorizationManager.FindByIdAsync(context.AuthorizationId, context.CancellationToken);
+ if (authorization is null || !await _authorizationManager.HasStatusAsync(authorization, Statuses.Valid, context.CancellationToken))
{
context.Logger.LogInformation(6006, SR.GetResourceString(SR.ID6006), context.AuthorizationId);
@@ -1562,16 +1562,16 @@ public static partial class OpenIddictServerHandlers
// If the client application is known, associate it with the token.
if (!string.IsNullOrEmpty(context.ClientId))
{
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- descriptor.ApplicationId = await _applicationManager.GetIdAsync(application);
+ descriptor.ApplicationId = await _applicationManager.GetIdAsync(application, context.CancellationToken);
}
- var token = await _tokenManager.CreateAsync(descriptor)
+ var token = await _tokenManager.CreateAsync(descriptor, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0019));
- var identifier = await _tokenManager.GetIdAsync(token);
+ var identifier = await _tokenManager.GetIdAsync(token, context.CancellationToken);
// Attach the token identifier to the principal so that it can be stored in the token payload.
context.Principal.SetTokenId(identifier);
@@ -1815,11 +1815,11 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0009));
}
- var token = await _tokenManager.FindByIdAsync(identifier)
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0021));
var descriptor = new OpenIddictTokenDescriptor();
- await _tokenManager.PopulateAsync(descriptor, token);
+ await _tokenManager.PopulateAsync(descriptor, token, context.CancellationToken);
// Attach the generated token to the token entry.
descriptor.Payload = context.Token;
@@ -1839,7 +1839,7 @@ public static partial class OpenIddictServerHandlers
// User codes are generally short. To help reduce the risks of collisions with
// existing entries, a database check is performed here before updating the entry.
- while (await _tokenManager.FindByReferenceIdAsync(descriptor.ReferenceId) is not null);
+ while (await _tokenManager.FindByReferenceIdAsync(descriptor.ReferenceId, context.CancellationToken) is not null);
}
else
@@ -1849,7 +1849,7 @@ public static partial class OpenIddictServerHandlers
}
}
- await _tokenManager.UpdateAsync(token, descriptor);
+ await _tokenManager.UpdateAsync(token, descriptor, context.CancellationToken);
context.Logger.LogTrace(6014, SR.GetResourceString(SR.ID6014), context.Token, identifier, context.TokenType);
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
index 5fc5f448..c08954c9 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs
@@ -469,11 +469,11 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the revocation endpoint.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Revocation))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.Revocation, context.CancellationToken))
{
context.Logger.LogInformation(6116, SR.GetResourceString(SR.ID6116), context.ClientId);
@@ -671,7 +671,7 @@ public static partial class OpenIddictServerHandlers
return;
}
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is null)
{
context.Logger.LogInformation(6123, SR.GetResourceString(SR.ID6123), identifier);
@@ -685,7 +685,7 @@ public static partial class OpenIddictServerHandlers
}
// Try to revoke the token. If an error occurs, return an error.
- if (!await _tokenManager.TryRevokeAsync(token))
+ if (!await _tokenManager.TryRevokeAsync(token, context.CancellationToken))
{
context.Reject(
error: Errors.UnsupportedTokenType,
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
index 30cf29b3..b148823d 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs
@@ -599,10 +599,10 @@ public static partial class OpenIddictServerHandlers
if (!string.IsNullOrEmpty(context.ClientId))
{
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
- if (!await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, context.PostLogoutRedirectUri))
+ if (!await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, context.PostLogoutRedirectUri, context.CancellationToken))
{
context.Logger.LogInformation(6128, SR.GetResourceString(SR.ID6128), context.PostLogoutRedirectUri);
@@ -634,17 +634,17 @@ public static partial class OpenIddictServerHandlers
// To be considered valid, a post_logout_redirect_uri must correspond to an existing client application
// that was granted the ept:logout permission, unless endpoint permissions checking was explicitly disabled.
- await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(uri))
+ await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(uri, context.CancellationToken))
{
// Note: the legacy "ept:logout" permission is still allowed for backward compatibility.
if (!context.Options.IgnoreEndpointPermissions &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession) &&
- !await _applicationManager.HasPermissionAsync(application, "ept:logout"))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession, context.CancellationToken) &&
+ !await _applicationManager.HasPermissionAsync(application, "ept:logout", context.CancellationToken))
{
continue;
}
- if (await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, uri))
+ if (await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, uri, context.CancellationToken))
{
return true;
}
@@ -667,18 +667,18 @@ public static partial class OpenIddictServerHandlers
string.Equals(value.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)))
{
await foreach (var application in _applicationManager.FindByPostLogoutRedirectUriAsync(
- uri: new UriBuilder(value) { Port = -1 }.Uri.AbsoluteUri))
+ uri: new UriBuilder(value) { Port = -1 }.Uri.AbsoluteUri, context.CancellationToken))
{
// Note: the legacy "ept:logout" permission is still allowed for backward compatibility.
if (!context.Options.IgnoreEndpointPermissions &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession) &&
- !await _applicationManager.HasPermissionAsync(application, "ept:logout"))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession, context.CancellationToken) &&
+ !await _applicationManager.HasPermissionAsync(application, "ept:logout", context.CancellationToken))
{
continue;
}
- if (await _applicationManager.HasApplicationTypeAsync(application, ApplicationTypes.Native) &&
- await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, uri))
+ if (await _applicationManager.HasApplicationTypeAsync(application, ApplicationTypes.Native, context.CancellationToken) &&
+ await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, uri, context.CancellationToken))
{
return true;
}
@@ -729,14 +729,14 @@ public static partial class OpenIddictServerHandlers
Debug.Assert(!string.IsNullOrEmpty(context.ClientId), SR.FormatID4000(Parameters.ClientId));
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Reject the request if the application is not allowed to use the end session endpoint.
//
// Note: the legacy "ept:logout" permission is still allowed for backward compatibility.
- if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession) &&
- !await _applicationManager.HasPermissionAsync(application, "ept:logout"))
+ if (!await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession, context.CancellationToken) &&
+ !await _applicationManager.HasPermissionAsync(application, "ept:logout", context.CancellationToken))
{
context.Logger.LogInformation(6048, SR.GetResourceString(SR.ID6048), context.ClientId);
@@ -858,7 +858,7 @@ public static partial class OpenIddictServerHandlers
foreach (var identifier in identifiers)
{
- var application = await _applicationManager.FindByClientIdAsync(identifier);
+ var application = await _applicationManager.FindByClientIdAsync(identifier, context.CancellationToken);
if (application is null)
{
continue;
@@ -866,13 +866,13 @@ public static partial class OpenIddictServerHandlers
// Note: the legacy "ept:logout" permission is still allowed for backward compatibility.
if (!context.Options.IgnoreEndpointPermissions &&
- !await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession) &&
- !await _applicationManager.HasPermissionAsync(application, "ept:logout"))
+ !await _applicationManager.HasPermissionAsync(application, Permissions.Endpoints.EndSession, context.CancellationToken) &&
+ !await _applicationManager.HasPermissionAsync(application, "ept:logout", context.CancellationToken))
{
continue;
}
- if (await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, uri))
+ if (await _applicationManager.ValidatePostLogoutRedirectUriAsync(application, uri, context.CancellationToken))
{
return true;
}
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
index a6517294..44a1a598 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
@@ -1046,7 +1046,7 @@ public static partial class OpenIddictServerHandlers
// 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);
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken);
if (application is null)
{
context.Logger.LogInformation(6221, SR.GetResourceString(SR.ID6221), context.ClientId);
@@ -1113,10 +1113,10 @@ public static partial class OpenIddictServerHandlers
return;
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
- if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
+ if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public, context.CancellationToken))
{
// Reject grant_type=client_credentials token requests if the application is a public client.
if (context.EndpointType is OpenIddictServerEndpointType.Token &&
@@ -1224,16 +1224,16 @@ public static partial class OpenIddictServerHandlers
return;
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// If the application is a public client, don't validate the client secret.
- if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
+ if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public, context.CancellationToken))
{
return;
}
- if (!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret))
+ if (!await _applicationManager.ValidateClientSecretAsync(application, context.ClientSecret, context.CancellationToken))
{
context.Logger.LogInformation(6225, SR.GetResourceString(SR.ID6225), context.ClientId);
@@ -1398,7 +1398,7 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0032));
// Note: to avoid building and introspecting a X.509 certificate chain and reduce the cost
@@ -1421,7 +1421,7 @@ public static partial class OpenIddictServerHandlers
}
if (await _applicationManager.GetSelfSignedTlsClientAuthenticationPolicyAsync(
- application, context.Options.SelfSignedTlsClientAuthenticationPolicy) is not X509ChainPolicy policy)
+ application, context.Options.SelfSignedTlsClientAuthenticationPolicy, context.CancellationToken) is not X509ChainPolicy policy)
{
context.Logger.LogInformation(6283, SR.GetResourceString(SR.ID6283), context.ClientId);
@@ -1442,7 +1442,7 @@ public static partial class OpenIddictServerHandlers
// To allow validating such certificates, the chain policy is amended to consider the specified
// self-signed certificate as a trusted root and basically disable chain validation while still
// validating the other aspects of the certificate (e.g expiration date, key usage, etc).
- if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
+ if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public, context.CancellationToken))
{
// Always clone the X.509 chain policy to ensure the original instance is never mutated.
policy = policy.Clone();
@@ -1455,7 +1455,7 @@ public static partial class OpenIddictServerHandlers
}
if (!await _applicationManager.ValidateSelfSignedTlsClientCertificateAsync(
- application, context.Transaction.RemoteCertificate, policy))
+ application, context.Transaction.RemoteCertificate, policy, context.CancellationToken))
{
context.Logger.LogInformation(6283, SR.GetResourceString(SR.ID6283), context.ClientId);
@@ -1481,9 +1481,9 @@ public static partial class OpenIddictServerHandlers
}
if (await _applicationManager.GetPublicKeyInfrastructureTlsClientAuthenticationPolicyAsync(
- application, context.Options.PublicKeyInfrastructureTlsClientAuthenticationPolicy) is not X509ChainPolicy policy ||
+ application, context.Options.PublicKeyInfrastructureTlsClientAuthenticationPolicy, context.CancellationToken) is not X509ChainPolicy policy ||
!await _applicationManager.ValidatePublicKeyInfrastructureTlsClientCertificateAsync(
- application, context.Transaction.RemoteCertificate, policy))
+ application, context.Transaction.RemoteCertificate, policy, context.CancellationToken))
{
context.Logger.LogInformation(6284, SR.GetResourceString(SR.ID6284), context.ClientId);
@@ -2663,10 +2663,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0008));
}
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is not null)
{
- await _tokenManager.TryRejectAsync(token);
+ await _tokenManager.TryRejectAsync(token, context.CancellationToken);
}
}
}
@@ -2719,10 +2719,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0009));
}
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is not null)
{
- await _tokenManager.TryRejectAsync(token);
+ await _tokenManager.TryRejectAsync(token, context.CancellationToken);
}
}
}
@@ -2988,7 +2988,7 @@ public static partial class OpenIddictServerHandlers
return;
}
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is null)
{
return;
@@ -2998,10 +2998,10 @@ public static partial class OpenIddictServerHandlers
// errors returned while trying to mark the entry as redeemed (that may be caused by concurrent requests).
if (context.EndpointType is OpenIddictServerEndpointType.Token && context.Request.IsRefreshTokenGrantType())
{
- await _tokenManager.TryRedeemAsync(token);
+ await _tokenManager.TryRedeemAsync(token, context.CancellationToken);
}
- else if (!await _tokenManager.TryRedeemAsync(token))
+ else if (!await _tokenManager.TryRedeemAsync(token, context.CancellationToken))
{
context.Reject(
error: Errors.InvalidToken,
@@ -3483,16 +3483,16 @@ public static partial class OpenIddictServerHandlers
// If the client application is known, associate it to the authorization.
if (!string.IsNullOrEmpty(context.Request.ClientId))
{
- var application = await _applicationManager.FindByClientIdAsync(context.Request.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.Request.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- descriptor.ApplicationId = await _applicationManager.GetIdAsync(application);
+ descriptor.ApplicationId = await _applicationManager.GetIdAsync(application, context.CancellationToken);
}
- var authorization = await _authorizationManager.CreateAsync(descriptor)
+ var authorization = await _authorizationManager.CreateAsync(descriptor, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0018));
- var identifier = await _authorizationManager.GetIdAsync(authorization);
+ var identifier = await _authorizationManager.GetIdAsync(authorization, context.CancellationToken);
if (string.IsNullOrEmpty(context.Request.ClientId))
{
@@ -3610,10 +3610,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.AccessToken, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -3744,10 +3744,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.AuthorizationCode, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -3868,10 +3868,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.DeviceCode, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -4084,7 +4084,7 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
var name = context.IssuedTokenType switch
@@ -4096,7 +4096,7 @@ public static partial class OpenIddictServerHandlers
_ => Settings.TokenLifetimes.IssuedToken
};
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(name, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -4178,7 +4178,7 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
// Note: refresh tokens are only bound to the provided certificate when the client
@@ -4186,7 +4186,7 @@ public static partial class OpenIddictServerHandlers
// are already sender-constrained via standard client authentication, which is more
// flexible than certificate-based token binding, as rotating client credentials is
// easier in that case (specially when using PKI-based mTLS client authentication).
- if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
+ if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public, context.CancellationToken))
{
principal.SetClaim(Claims.Confirmation, CreateConfirmationClaim(certificate));
}
@@ -4274,10 +4274,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.RequestToken, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -4419,10 +4419,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.RefreshToken, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -4472,7 +4472,7 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
// Note: refresh tokens are only bound to the provided certificate when the client
@@ -4480,7 +4480,7 @@ public static partial class OpenIddictServerHandlers
// are already sender-constrained via standard client authentication, which is more
// flexible than certificate-based token binding, as rotating client credentials is
// easier in that case (specially when using PKI-based mTLS client authentication).
- if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public))
+ if (await _applicationManager.HasClientTypeAsync(application, ClientTypes.Public, context.CancellationToken))
{
principal.SetClaim(Claims.Confirmation, CreateConfirmationClaim(certificate));
}
@@ -4594,10 +4594,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.IdentityToken, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -4718,10 +4718,10 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
}
- var application = await _applicationManager.FindByClientIdAsync(context.ClientId)
+ var application = await _applicationManager.FindByClientIdAsync(context.ClientId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0017));
- var settings = await _applicationManager.GetSettingsAsync(application);
+ var settings = await _applicationManager.GetSettingsAsync(application, context.CancellationToken);
if (settings.TryGetValue(Settings.TokenLifetimes.UserCode, out string? setting) &&
TimeSpan.TryParse(setting, CultureInfo.InvariantCulture, out var value))
{
@@ -5255,13 +5255,13 @@ public static partial class OpenIddictServerHandlers
throw new InvalidOperationException(SR.GetResourceString(SR.ID0008));
}
- var token = await _tokenManager.FindByIdAsync(identifier)
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0265));
// Replace the device code details by the payload derived from the new device code principal,
// that includes all the user claims populated by the application after authenticating the user.
var descriptor = new OpenIddictTokenDescriptor();
- await _tokenManager.PopulateAsync(descriptor, token);
+ await _tokenManager.PopulateAsync(descriptor, token, context.CancellationToken);
// Note: the lifetime is deliberately extended to give more time to the client to redeem the code.
descriptor.ExpirationDate = context.DeviceCodePrincipal.GetExpirationDate();
@@ -5270,9 +5270,9 @@ public static partial class OpenIddictServerHandlers
descriptor.Status = Statuses.Valid;
descriptor.Subject = context.DeviceCodePrincipal.GetClaim(Claims.Subject);
- await _tokenManager.UpdateAsync(token, descriptor);
+ await _tokenManager.UpdateAsync(token, descriptor, context.CancellationToken);
- context.Logger.LogTrace(6021, SR.GetResourceString(SR.ID6021), await _tokenManager.GetIdAsync(token));
+ context.Logger.LogTrace(6021, SR.GetResourceString(SR.ID6021), await _tokenManager.GetIdAsync(token, context.CancellationToken));
}
}
@@ -5850,14 +5850,14 @@ public static partial class OpenIddictServerHandlers
return;
}
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is null)
{
return;
}
// Mark the token as redeemed to prevent future reuses.
- await _tokenManager.TryRedeemAsync(token);
+ await _tokenManager.TryRedeemAsync(token, context.CancellationToken);
}
}
diff --git a/src/OpenIddict.Server/OpenIddictServerTransaction.cs b/src/OpenIddict.Server/OpenIddictServerTransaction.cs
index 3720f112..49b63487 100644
--- a/src/OpenIddict.Server/OpenIddictServerTransaction.cs
+++ b/src/OpenIddict.Server/OpenIddictServerTransaction.cs
@@ -17,14 +17,8 @@ namespace OpenIddict.Server;
public sealed class OpenIddictServerTransaction
{
///
- /// Gets or sets the cancellation token that will be
- /// used to determine if the operation was aborted.
+ /// Gets or sets the cancellation token used to determine if the operation was aborted.
///
- ///
- /// Note: for security reasons, this property shouldn't be used by event
- /// handlers to abort security-sensitive operations. As such, it is
- /// recommended to use this property only for user-dependent operations.
- ///
public CancellationToken CancellationToken { get; set; }
///
diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
index 7d2a633e..953fabc5 100644
--- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
+++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs
@@ -42,13 +42,23 @@ public sealed class OpenIddictValidationAspNetCoreHandler : AuthenticationHandle
///
public async Task HandleRequestAsync()
{
+ // Note: to ensure internal operations are not immediately cancelled when the request is aborted
+ // (which may represent a security risk if sensitive operations are in progress), an ad-hoc token
+ // source is always created and configured to be triggered 5 seconds after the request is aborted.
+ var source = new CancellationTokenSource();
+ var registration = Context.RequestAborted.Register(static state =>
+ ((CancellationTokenSource) state!).CancelAfter(TimeSpan.FromSeconds(5)), source);
+
+ Response.RegisterForDispose(source);
+ Response.RegisterForDispose(registration);
+
// Note: the transaction may be already attached when replaying an ASP.NET Core request
// (e.g when using the built-in status code pages middleware with the re-execute mode).
var transaction = Context.Features.Get()?.Transaction;
if (transaction is null)
{
// Create a new transaction and attach the HTTP request to make it available to the ASP.NET Core handlers.
- transaction = await _factory.CreateTransactionAsync();
+ transaction = await _factory.CreateTransactionAsync(source.Token);
transaction.Properties[typeof(HttpRequest).FullName!] = new WeakReference(Request);
// Attach the OpenIddict validation transaction to the ASP.NET Core features
@@ -56,11 +66,7 @@ public sealed class OpenIddictValidationAspNetCoreHandler : AuthenticationHandle
Context.Features.Set(new OpenIddictValidationAspNetCoreFeature { Transaction = transaction });
}
- var context = new ProcessRequestContext(transaction)
- {
- CancellationToken = Context.RequestAborted
- };
-
+ var context = new ProcessRequestContext(transaction);
await _dispatcher.DispatchAsync(context);
if (context.IsRequestHandled)
@@ -77,7 +83,6 @@ public sealed class OpenIddictValidationAspNetCoreHandler : AuthenticationHandle
{
var notification = new ProcessErrorContext(transaction)
{
- CancellationToken = Context.RequestAborted,
Error = context.Error ?? Errors.InvalidRequest,
ErrorDescription = context.ErrorDescription,
ErrorUri = context.ErrorUri,
@@ -114,10 +119,7 @@ public sealed class OpenIddictValidationAspNetCoreHandler : AuthenticationHandle
var context = transaction.GetProperty(typeof(ProcessAuthenticationContext).FullName!);
if (context is null)
{
- await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction)
- {
- CancellationToken = Context.RequestAborted
- });
+ await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction));
// 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.
@@ -214,7 +216,6 @@ public sealed class OpenIddictValidationAspNetCoreHandler : AuthenticationHandle
var context = new ProcessChallengeContext(transaction)
{
- CancellationToken = Context.RequestAborted,
Response = new OpenIddictResponse()
};
@@ -229,7 +230,6 @@ public sealed class OpenIddictValidationAspNetCoreHandler : AuthenticationHandle
{
var notification = new ProcessErrorContext(transaction)
{
- CancellationToken = Context.RequestAborted,
Error = context.Error ?? Errors.InvalidRequest,
ErrorDescription = context.ErrorDescription,
ErrorUri = context.ErrorUri,
diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs
index 19a756f1..a91401ba 100644
--- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs
+++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs
@@ -332,7 +332,7 @@ public static partial class OpenIddictValidationAspNetCoreHandlers
// If a client certificate was used during the TLS handshake, attach it to the context.
if (request.IsHttps && await request.HttpContext.Connection.GetClientCertificateAsync(
- request.HttpContext.RequestAborted) is X509Certificate2 certificate)
+ context.CancellationToken) is X509Certificate2 certificate)
{
context.Transaction.RemoteCertificate = certificate;
}
diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
index 606c1994..cb4251a2 100644
--- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
+++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs
@@ -37,13 +37,23 @@ public sealed class OpenIddictValidationOwinHandler : AuthenticationHandler
protected override async Task InitializeCoreAsync()
{
+ // Note: to ensure internal operations are not immediately cancelled when the request is aborted
+ // (which may represent a security risk if sensitive operations are in progress), an ad-hoc token
+ // source is always created and configured to be triggered 5 seconds after the request is aborted.
+ var source = new CancellationTokenSource();
+ var registration = Request.CallCancelled.Register(static state =>
+ ((CancellationTokenSource) state!).CancelAfter(TimeSpan.FromSeconds(5)), source);
+
+ Response.OnSendingHeaders(static state => ((CancellationTokenSource) state!).Dispose(), source);
+ Response.OnSendingHeaders(static state => ((CancellationTokenRegistration) state!).Dispose(), registration);
+
// Note: the transaction may be already attached when replaying an OWIN request
// (e.g when using a status code pages middleware re-invoking the OWIN pipeline).
var transaction = Context.Get(typeof(OpenIddictValidationTransaction).FullName);
if (transaction is null)
{
// Create a new transaction and attach the OWIN request to make it available to the OWIN handlers.
- transaction = await _factory.CreateTransactionAsync();
+ transaction = await _factory.CreateTransactionAsync(source.Token);
transaction.Properties[typeof(IOwinRequest).FullName!] = new WeakReference(Request);
// Attach the OpenIddict validation transaction to the OWIN shared dictionary
@@ -51,11 +61,7 @@ public sealed class OpenIddictValidationOwinHandler : AuthenticationHandler(typeof(ProcessAuthenticationContext).FullName!);
if (context is null)
{
- await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction)
- {
- CancellationToken = Request.CallCancelled
- });
+ await _dispatcher.DispatchAsync(context = new ProcessAuthenticationContext(transaction));
// 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.
@@ -222,7 +224,6 @@ public sealed class OpenIddictValidationOwinHandler : AuthenticationHandler GetClientCertificateAsync(IOwinContext context)
+ static async ValueTask GetClientCertificateAsync(
+ IOwinContext context, CancellationToken cancellationToken)
{
// If a loading function was provided by the OWIN host, always invoke it before trying
// to resolve the certificate to ensure it is present in the environment dictionary.
if (context.Get>("ssl.LoadClientCertAsync") is Func loader)
{
- await loader();
+ await loader().WaitAsync(cancellationToken);
}
return context.Get("ssl.ClientCertificate") is X509Certificate certificate
diff --git a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
index 602470a5..37bed945 100644
--- a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
+++ b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs
@@ -607,7 +607,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
else if (string.Equals(encoding, ContentEncodings.Gzip, StringComparison.OrdinalIgnoreCase))
{
- stream ??= await response.Content.ReadAsStreamAsync();
+ stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken);
stream = new GZipStream(stream, CompressionMode.Decompress);
}
@@ -621,13 +621,13 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
// For more information, read https://www.rfc-editor.org/rfc/rfc9110.html#name-deflate-coding.
else if (string.Equals(encoding, ContentEncodings.Deflate, StringComparison.OrdinalIgnoreCase))
{
- stream ??= await response.Content.ReadAsStreamAsync();
+ stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken);
stream = new ZLibStream(stream, CompressionMode.Decompress);
}
else if (string.Equals(encoding, ContentEncodings.Brotli, StringComparison.OrdinalIgnoreCase))
{
- stream ??= await response.Content.ReadAsStreamAsync();
+ stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken);
stream = new BrotliStream(stream, CompressionMode.Decompress);
}
#endif
@@ -651,7 +651,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
// (e.g if the JSON deserialization process fails, the stream is read as a string
// during a second pass a second time for logging/debuggability purposes).
var content = new StreamContent(stream);
- await content.LoadIntoBufferAsync();
+ await content.LoadIntoBufferAsync(context.CancellationToken);
// Copy the headers from the original content to the new instance.
foreach (var header in response.Content.Headers)
@@ -724,7 +724,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
catch (Exception exception) when (!OpenIddictHelpers.IsFatal(exception))
{
context.Logger.LogError(6183, exception, SR.GetResourceString(SR.ID6183),
- await response.Content.ReadAsStringAsync());
+ await response.Content.ReadAsStringAsync(context.CancellationToken));
context.Reject(
error: Errors.ServerError,
@@ -902,7 +902,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
if (!response.IsSuccessStatusCode && string.IsNullOrEmpty(context.Transaction.Response?.Error))
{
context.Logger.LogError(6184, SR.GetResourceString(SR.ID6184), response.StatusCode,
- await response.Content.ReadAsStringAsync());
+ await response.Content.ReadAsStringAsync(context.CancellationToken));
context.Reject(
error: (int) response.StatusCode switch
@@ -926,7 +926,7 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
if (context.Transaction.Response is null)
{
context.Logger.LogError(6185, SR.GetResourceString(SR.ID6185), response.StatusCode,
- response.Content.Headers.ContentType, await response.Content.ReadAsStringAsync());
+ response.Content.Headers.ContentType, await response.Content.ReadAsStringAsync(context.CancellationToken));
context.Reject(
error: Errors.ServerError,
diff --git a/src/OpenIddict.Validation/IOpenIddictValidationFactory.cs b/src/OpenIddict.Validation/IOpenIddictValidationFactory.cs
index d88c5d26..5ad893d4 100644
--- a/src/OpenIddict.Validation/IOpenIddictValidationFactory.cs
+++ b/src/OpenIddict.Validation/IOpenIddictValidationFactory.cs
@@ -18,9 +18,13 @@ public interface IOpenIddictValidationFactory
/// Creates a new that is used as a
/// way to store per-request data needed to process the requested operation.
///
+ /// The that can be used to abort the operation.
+ ///
+ /// Note: the specified is automatically attached to the returned transaction.
+ ///
///
/// A that can be used to monitor the asynchronous
/// operation, whose result returns the created transaction.
///
- ValueTask CreateTransactionAsync();
+ ValueTask CreateTransactionAsync(CancellationToken cancellationToken);
}
diff --git a/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs b/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
index 61ecfcc4..b0fc80e1 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationDispatcher.cs
@@ -40,6 +40,8 @@ public sealed class OpenIddictValidationDispatcher : IOpenIddictValidationDispat
await foreach (var handler in GetHandlersAsync())
{
+ context.CancellationToken.ThrowIfCancellationRequested();
+
try
{
await handler.HandleAsync(context);
diff --git a/src/OpenIddict.Validation/OpenIddictValidationEvents.cs b/src/OpenIddict.Validation/OpenIddictValidationEvents.cs
index eea07a41..0fd03904 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationEvents.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationEvents.cs
@@ -31,19 +31,9 @@ public static partial class OpenIddictValidationEvents
public OpenIddictValidationTransaction Transaction { get; }
///
- /// Gets or sets the cancellation token that will be
- /// used to determine if the operation was aborted.
+ /// Gets the cancellation token used to determine if the operation was aborted.
///
- ///
- /// Note: for security reasons, this property shouldn't be used by event
- /// handlers to abort security-sensitive operations. As such, it is
- /// recommended to use this property only for user-dependent operations.
- ///
- public CancellationToken CancellationToken
- {
- get => Transaction.CancellationToken;
- set => Transaction.CancellationToken = value;
- }
+ public CancellationToken CancellationToken => Transaction.CancellationToken;
///
/// Gets or sets the endpoint type that handled the request, if applicable.
diff --git a/src/OpenIddict.Validation/OpenIddictValidationFactory.cs b/src/OpenIddict.Validation/OpenIddictValidationFactory.cs
index 85e836c9..4b806f42 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationFactory.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationFactory.cs
@@ -31,10 +31,18 @@ public sealed class OpenIddictValidationFactory : IOpenIddictValidationFactory
}
///
- public ValueTask CreateTransactionAsync()
- => new(new OpenIddictValidationTransaction
+ public ValueTask CreateTransactionAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return new(Task.FromCanceled(cancellationToken));
+ }
+
+ return new(new OpenIddictValidationTransaction
{
+ CancellationToken = cancellationToken,
Logger = _logger,
Options = _options.CurrentValue
});
+ }
}
diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
index 7c79cce3..1a49d049 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs
@@ -220,7 +220,7 @@ public static partial class OpenIddictValidationHandlers
}
// If the reference token cannot be found, don't return an error to allow another handler to validate it.
- var token = await _tokenManager.FindByReferenceIdAsync(context.Token);
+ var token = await _tokenManager.FindByReferenceIdAsync(context.Token, context.CancellationToken);
if (token is null)
{
return;
@@ -230,8 +230,8 @@ public static partial class OpenIddictValidationHandlers
if (!(context.ValidTokenTypes.Count switch
{
0 => true, // If no specific token type is expected, accept all token types at this stage.
- 1 => await _tokenManager.HasTypeAsync(token, context.ValidTokenTypes.ElementAt(0)),
- _ => await _tokenManager.HasTypeAsync(token, [.. context.ValidTokenTypes])
+ 1 => await _tokenManager.HasTypeAsync(token, context.ValidTokenTypes.ElementAt(0), context.CancellationToken),
+ _ => await _tokenManager.HasTypeAsync(token, [.. context.ValidTokenTypes], context.CancellationToken)
}))
{
context.Reject(
@@ -242,7 +242,7 @@ public static partial class OpenIddictValidationHandlers
return;
}
- var payload = await _tokenManager.GetPayloadAsync(token);
+ var payload = await _tokenManager.GetPayloadAsync(token, context.CancellationToken);
if (string.IsNullOrEmpty(payload))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0026));
@@ -253,7 +253,7 @@ public static partial class OpenIddictValidationHandlers
// used to restore the properties associated with the token.
context.IsReferenceToken = true;
context.Token = payload;
- context.TokenId = await _tokenManager.GetIdAsync(token);
+ context.TokenId = await _tokenManager.GetIdAsync(token, context.CancellationToken);
}
}
@@ -562,7 +562,7 @@ public static partial class OpenIddictValidationHandlers
}
// If the token entry cannot be found, return a generic error.
- var token = await _tokenManager.FindByIdAsync(identifier);
+ var token = await _tokenManager.FindByIdAsync(identifier, context.CancellationToken);
if (token is null)
{
context.Reject(
@@ -576,9 +576,9 @@ public static partial class OpenIddictValidationHandlers
// If the token was not validated as a reference token but has a reference identifier attached, this
// may indicate that the payload stored in the database has leaked and is being used as a regular,
// non-reference token. To prevent this, reject the token if the reference identifier is not null.
- if (!context.IsReferenceToken && !string.IsNullOrEmpty(await _tokenManager.GetReferenceIdAsync(token)))
+ if (!context.IsReferenceToken && !string.IsNullOrEmpty(await _tokenManager.GetReferenceIdAsync(token, context.CancellationToken)))
{
- context.Logger.LogWarning(6292, SR.GetResourceString(SR.ID6292), await _tokenManager.GetIdAsync(token));
+ context.Logger.LogWarning(6292, SR.GetResourceString(SR.ID6292), await _tokenManager.GetIdAsync(token, context.CancellationToken));
context.Reject(
error: Errors.InvalidToken,
@@ -590,11 +590,11 @@ public static partial class OpenIddictValidationHandlers
// Restore the creation/expiration dates/identifiers from the token entry metadata.
context.Principal
- .SetCreationDate(await _tokenManager.GetCreationDateAsync(token))
- .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token))
- .SetAuthorizationId(context.AuthorizationId = await _tokenManager.GetAuthorizationIdAsync(token))
- .SetTokenId(context.TokenId = await _tokenManager.GetIdAsync(token))
- .SetTokenType(await _tokenManager.GetTypeAsync(token));
+ .SetCreationDate(await _tokenManager.GetCreationDateAsync(token, context.CancellationToken))
+ .SetExpirationDate(await _tokenManager.GetExpirationDateAsync(token, context.CancellationToken))
+ .SetAuthorizationId(context.AuthorizationId = await _tokenManager.GetAuthorizationIdAsync(token, context.CancellationToken))
+ .SetTokenId(context.TokenId = await _tokenManager.GetIdAsync(token, context.CancellationToken))
+ .SetTokenType(await _tokenManager.GetTypeAsync(token, context.CancellationToken));
}
}
@@ -922,10 +922,10 @@ public static partial class OpenIddictValidationHandlers
Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.TokenId), SR.GetResourceString(SR.ID4017));
- var token = await _tokenManager.FindByIdAsync(context.TokenId)
+ var token = await _tokenManager.FindByIdAsync(context.TokenId, context.CancellationToken)
?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0021));
- if (!await _tokenManager.HasStatusAsync(token, Statuses.Valid))
+ if (!await _tokenManager.HasStatusAsync(token, Statuses.Valid, context.CancellationToken))
{
context.Logger.LogInformation(6005, SR.GetResourceString(SR.ID6005), context.TokenId);
@@ -972,8 +972,8 @@ public static partial class OpenIddictValidationHandlers
Debug.Assert(context.Principal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
Debug.Assert(!string.IsNullOrEmpty(context.AuthorizationId), SR.GetResourceString(SR.ID4018));
- var authorization = await _authorizationManager.FindByIdAsync(context.AuthorizationId);
- if (authorization is null || !await _authorizationManager.HasStatusAsync(authorization, Statuses.Valid))
+ var authorization = await _authorizationManager.FindByIdAsync(context.AuthorizationId, context.CancellationToken);
+ if (authorization is null || !await _authorizationManager.HasStatusAsync(authorization, Statuses.Valid, context.CancellationToken))
{
context.Logger.LogInformation(6006, SR.GetResourceString(SR.ID6006), context.AuthorizationId);
diff --git a/src/OpenIddict.Validation/OpenIddictValidationService.cs b/src/OpenIddict.Validation/OpenIddictValidationService.cs
index 5dbe97c0..b3da7d7a 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationService.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationService.cs
@@ -47,7 +47,7 @@ public class OpenIddictValidationService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
var context = new ProcessAuthenticationContext(transaction)
{
@@ -92,7 +92,7 @@ public class OpenIddictValidationService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
var request = new OpenIddictRequest();
request = await PrepareConfigurationRequestAsync();
@@ -214,7 +214,7 @@ public class OpenIddictValidationService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
var request = new OpenIddictRequest();
request = await PrepareJsonWebKeySetRequestAsync();
@@ -344,7 +344,7 @@ public class OpenIddictValidationService
var dispatcher = scope.ServiceProvider.GetRequiredService();
var factory = scope.ServiceProvider.GetRequiredService();
- var transaction = await factory.CreateTransactionAsync();
+ var transaction = await factory.CreateTransactionAsync(cancellationToken);
request = await PrepareIntrospectionRequestAsync();
request = await ApplyIntrospectionRequestAsync();
@@ -357,7 +357,6 @@ public class OpenIddictValidationService
{
var context = new PrepareIntrospectionRequestContext(transaction)
{
- CancellationToken = cancellationToken,
ClientAuthenticationMethod = method,
Configuration = configuration,
RemoteUri = uri,
@@ -381,7 +380,6 @@ public class OpenIddictValidationService
{
var context = new ApplyIntrospectionRequestContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Request = request
@@ -405,7 +403,6 @@ public class OpenIddictValidationService
{
var context = new ExtractIntrospectionResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Request = request
@@ -431,7 +428,6 @@ public class OpenIddictValidationService
{
var context = new HandleIntrospectionResponseContext(transaction)
{
- CancellationToken = cancellationToken,
RemoteUri = uri,
Configuration = configuration,
Request = request,
diff --git a/src/OpenIddict.Validation/OpenIddictValidationTransaction.cs b/src/OpenIddict.Validation/OpenIddictValidationTransaction.cs
index 8d04dc98..341f851a 100644
--- a/src/OpenIddict.Validation/OpenIddictValidationTransaction.cs
+++ b/src/OpenIddict.Validation/OpenIddictValidationTransaction.cs
@@ -17,14 +17,8 @@ namespace OpenIddict.Validation;
public sealed class OpenIddictValidationTransaction
{
///
- /// Gets or sets the cancellation token that will be
- /// used to determine if the operation was aborted.
+ /// Gets or sets the cancellation token used to determine if the operation was aborted.
///
- ///
- /// Note: for security reasons, this property shouldn't be used by event
- /// handlers to abort security-sensitive operations. As such, it is
- /// recommended to use this property only for user-dependent operations.
- ///
public CancellationToken CancellationToken { get; set; }
///