|
|
|
@ -24,7 +24,7 @@ namespace OpenIddict.Core |
|
|
|
public class OpenIddictAuthorizationCache<TAuthorization> : IOpenIddictAuthorizationCache<TAuthorization>, IDisposable where TAuthorization : class |
|
|
|
{ |
|
|
|
private readonly MemoryCache _cache; |
|
|
|
private readonly ConcurrentDictionary<string, Lazy<CancellationTokenSource>> _signals; |
|
|
|
private readonly ConcurrentDictionary<string, CancellationTokenSource> _signals; |
|
|
|
private readonly IOpenIddictAuthorizationStore<TAuthorization> _store; |
|
|
|
|
|
|
|
public OpenIddictAuthorizationCache( |
|
|
|
@ -36,7 +36,7 @@ namespace OpenIddict.Core |
|
|
|
SizeLimit = options.CurrentValue.EntityCacheLimit |
|
|
|
}); |
|
|
|
|
|
|
|
_signals = new ConcurrentDictionary<string, Lazy<CancellationTokenSource>>(StringComparer.Ordinal); |
|
|
|
_signals = new ConcurrentDictionary<string, CancellationTokenSource>(StringComparer.Ordinal); |
|
|
|
_store = resolver.Get<TAuthorization>(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -97,7 +97,7 @@ namespace OpenIddict.Core |
|
|
|
Subject = await _store.GetSubjectAsync(authorization, cancellationToken) |
|
|
|
}); |
|
|
|
|
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -122,7 +122,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
foreach (var signal in _signals) |
|
|
|
{ |
|
|
|
signal.Value.Value.Dispose(); |
|
|
|
signal.Value.Dispose(); |
|
|
|
} |
|
|
|
|
|
|
|
_cache.Dispose(); |
|
|
|
@ -175,7 +175,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
foreach (var authorization in authorizations) |
|
|
|
{ |
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -248,7 +248,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
foreach (var authorization in authorizations) |
|
|
|
{ |
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -328,7 +328,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
foreach (var authorization in authorizations) |
|
|
|
{ |
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -441,7 +441,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
foreach (var authorization in authorizations) |
|
|
|
{ |
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -498,7 +498,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
if (authorization != null) |
|
|
|
{ |
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -556,7 +556,7 @@ namespace OpenIddict.Core |
|
|
|
{ |
|
|
|
foreach (var authorization in authorizations) |
|
|
|
{ |
|
|
|
var signal = await CreateExpirationTokenAsync(authorization, cancellationToken); |
|
|
|
var signal = await CreateExpirationSignalAsync(authorization, cancellationToken); |
|
|
|
if (signal == null) |
|
|
|
{ |
|
|
|
throw new InvalidOperationException("An error occurred while creating an expiration signal."); |
|
|
|
@ -596,9 +596,9 @@ namespace OpenIddict.Core |
|
|
|
throw new InvalidOperationException("The application identifier cannot be extracted."); |
|
|
|
} |
|
|
|
|
|
|
|
if (_signals.TryGetValue(identifier, out Lazy<CancellationTokenSource> signal)) |
|
|
|
if (_signals.TryGetValue(identifier, out CancellationTokenSource signal)) |
|
|
|
{ |
|
|
|
signal.Value.Cancel(); |
|
|
|
signal.Cancel(); |
|
|
|
|
|
|
|
_signals.TryRemove(identifier, out signal); |
|
|
|
} |
|
|
|
@ -614,7 +614,7 @@ namespace OpenIddict.Core |
|
|
|
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
|
|
|
|
/// whose result returns an expiration signal for the specified authorization.
|
|
|
|
/// </returns>
|
|
|
|
protected virtual async Task<IChangeToken> CreateExpirationTokenAsync( |
|
|
|
protected virtual async Task<IChangeToken> CreateExpirationSignalAsync( |
|
|
|
[NotNull] TAuthorization authorization, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
if (authorization == null) |
|
|
|
@ -628,15 +628,9 @@ namespace OpenIddict.Core |
|
|
|
throw new InvalidOperationException("The authorization identifier cannot be extracted."); |
|
|
|
} |
|
|
|
|
|
|
|
var signal = _signals.GetOrAdd(identifier, delegate |
|
|
|
{ |
|
|
|
// Note: a Lazy<CancellationTokenSource> is used here to ensure only one CancellationTokenSource
|
|
|
|
// can be created. Not doing so would result in expiration signals being potentially linked to
|
|
|
|
// multiple sources, with a single one of them being eventually tracked and thus, cancelable.
|
|
|
|
return new Lazy<CancellationTokenSource>(() => new CancellationTokenSource()); |
|
|
|
}); |
|
|
|
var signal = _signals.GetOrAdd(identifier, _ => new CancellationTokenSource()); |
|
|
|
|
|
|
|
return new CancellationChangeToken(signal.Value.Token); |
|
|
|
return new CancellationChangeToken(signal.Token); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|