diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
index 60b0765d..bbd62009 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
@@ -190,6 +190,35 @@ namespace OpenIddict.Core
return Store.FindAsync(subject, client, cancellationToken);
}
+ ///
+ /// Retrieves the authorizations corresponding to the specified subject, associated with
+ /// the application identifier and for which the specified scopes have been granted.
+ ///
+ /// The subject associated with the authorization.
+ /// The client associated with the authorization.
+ /// The minimal scopes associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result
+ /// returns the authorizations corresponding to the specified subject/client/scopes.
+ ///
+ public virtual Task> FindAsync(
+ [NotNull] string subject, [NotNull] string client,
+ ImmutableArray scopes, CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrEmpty(subject))
+ {
+ throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
+ }
+
+ if (string.IsNullOrEmpty(client))
+ {
+ throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client));
+ }
+
+ return Store.FindAsync(subject, client, scopes, cancellationToken);
+ }
+
///
/// Retrieves an authorization using its unique identifier.
///
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
index 639b62c1..94e0146b 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
@@ -75,6 +75,22 @@ namespace OpenIddict.Core
///
Task> FindAsync([NotNull] string subject, [NotNull] string client, CancellationToken cancellationToken);
+ ///
+ /// Retrieves the authorizations corresponding to the specified subject, associated with
+ /// the application identifier and for which the specified scopes have been granted.
+ ///
+ /// The subject associated with the authorization.
+ /// The client associated with the authorization.
+ /// The minimal scopes associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result
+ /// returns the authorizations corresponding to the specified subject/client/scopes.
+ ///
+ Task> FindAsync(
+ [NotNull] string subject, [NotNull] string client,
+ ImmutableArray scopes, CancellationToken cancellationToken);
+
///
/// Retrieves an authorization using its unique identifier.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
index 520053ba..acdd7e25 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
@@ -5,6 +5,7 @@
*/
using System;
+using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Linq;
@@ -111,6 +112,46 @@ namespace OpenIddict.Core
(key: ConvertIdentifierFromString(client), principal: subject), cancellationToken);
}
+ ///
+ /// Retrieves the authorizations corresponding to the specified subject, associated with
+ /// the application identifier and for which the specified scopes have been granted.
+ ///
+ /// The subject associated with the authorization.
+ /// The client associated with the authorization.
+ /// The minimal scopes associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result
+ /// returns the authorizations corresponding to the specified subject/client/scopes.
+ ///
+ public virtual async Task> FindAsync(
+ [NotNull] string subject, [NotNull] string client,
+ ImmutableArray scopes, CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrEmpty(subject))
+ {
+ throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
+ }
+
+ if (string.IsNullOrEmpty(client))
+ {
+ throw new ArgumentException("The client cannot be null or empty.", nameof(client));
+ }
+
+ var builder = ImmutableArray.CreateBuilder();
+
+ foreach (var authorization in await FindAsync(subject, client, cancellationToken))
+ {
+ var set = new HashSet(await GetScopesAsync(authorization, cancellationToken), StringComparer.Ordinal);
+ if (set.IsSupersetOf(scopes))
+ {
+ builder.Add(authorization);
+ }
+ }
+
+ return builder.ToImmutable();
+ }
+
///
/// Retrieves an authorization using its unique identifier.
///