'Custom Roles class for ApiAuthorizationDbContext

For the past 2 days I have been trying to get ApiAuthorizationDbContext to set a custom IdentityRole. With IdentityDbContext this could be done as follows:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

In the blazor project template the declaration of the ApplicationDbContext is the following:

public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser>
{
    public ApplicationDbContext(
        DbContextOptions options,
        IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
    {
    }
}

How can I do something similar with the ApiAuthorizationDbContext. I can not find this kind of support from the ApiAuthorizationDbContext class.

Thanks.



Solution 1:[1]

From @javiercn

ApiAuthorizationDbContext is a convenience class to get you started.

https://github.com/dotnet/aspnetcore/issues/14161#issuecomment-533468760

I created this ApplicationApiAuthorizationDbContext to get it working with roles.

//Based on Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ApiAuthorizationDbContext, Version=6.0.2.0
//https://github.com/dotnet/aspnetcore/issues/14161#issuecomment-533468760
public class ApplicationApiAuthorizationDbContext<TUser, TRole> : IdentityDbContext<TUser, TRole, string>, IPersistedGrantDbContext, IDisposable where TUser : IdentityUser where TRole : IdentityRole
{
    private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;

    public DbSet<PersistedGrant> PersistedGrants
    {
        get;
        set;
    }

    public DbSet<DeviceFlowCodes> DeviceFlowCodes
    {
        get;
        set;
    }

    public DbSet<Key> Keys
    {
        get;
        set;
    }

    public ApplicationApiAuthorizationDbContext(DbContextOptions options, IOptions<OperationalStoreOptions> operationalStoreOptions)
        : base(options)
    {
        _operationalStoreOptions = operationalStoreOptions;
    }

    Task<int> IPersistedGrantDbContext.SaveChangesAsync()
    {
        return base.SaveChangesAsync();
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value);
    }
}

Complete examples with added roles in EF Core 5.0 and EF Core 6.0:

https://stackoverflow.com/a/71321924/3850405

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ogglas