Search code examples
.netopeniddict

Using FindByResourceAsync in IOpenIddictScopeManager


I need to use IOpenIddictScopeManager.FindByResourceAsync to retrieve scopes associated with a resource, I only need the scope name not the whole descriptor object, but the return type is IAsyncEnumerable<object> and the runtime type is not of what I expected to be OpenIddictScopeDescriptor but OpenIddictEntityFrameworkCoreScope.

My usage:

foreach (var resource in resources)
{
    var associatedUserScopes = (await _scopeManager.FindByResourceAsync(resource).ToListAsync())
        .Select(sc=> ((OpenIddictEntityFrameworkCoreScope)sc).Name);

}

I didn't find any online resources that use FindByResourceAsync API, so I'm not sure if using OpenIddictEntityFrameworkCoreScope is the correct way to resolve the object returned by this API, it seems a type clients shouldn't interact with.


Solution

  • All the IOpenIddict*Manager interfaces are "untyped": the entity type used in the API signatures (parameters and return types) is always object and the actual entity type is only known at runtime (and depends on the stores you're using).

    To get the name of a scope instance, use the GetNameAsync() accessor:

    List<string> names = [];
    
    await foreach (var scope in manager.FindByResourceAsync("resource"))
    {
        names.Add(await manager.GetNameAsync(scope));
    }
    

    Alternatively, you can use the strongly-typed/generic OpenIddict*Manager<T> instead of the non-generic interfaces (e.g OpenIddictScopeManager<OpenIddictEntityFrameworkCoreScope>): in this case, the actual entity type is known at build time and all its properties can be directly accessed.

    List<string> names = [];
    
    await foreach (var scope in manager.FindByResourceAsync("resource"))
    {
        names.Add(scope.Name);
    }