Reputation: 357
I'm working with ASP .NET Core 3.0 with Angular project. I see this new ApiAuthorizationDbContext
and I wanted to override the table name and user id (to int) but there is no way I can do it. Does any body know a trick?
This is the class for the context to override the table name but it creates AspNetUser
and User
table. Why doesn't it just create one as usual?
public class ApplicationDbContext : ApiAuthorizationDbContext<AppUser>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AppUser>(entity => { entity.ToTable(name: "User"); });
modelBuilder.Entity<AppRole>(entity => { entity.ToTable(name: "Role"); });
}
}
Here is my user:
public class AppUser : IdentityUser
{
}
Normaly I override the primary key with AppUser<int>
but it doesn't work because of the ApiAuthorizationDbContext
.
Any ideas?
Upvotes: 21
Views: 12345
Reputation: 181
As far as I can see ApiAuthorizationDbContext just implements IPersistedGrantDbContext. Looks like a templates class
To use custom keys I have implemented IPersistedGrantDbContext in my ApplicationDbContext see below.
Remember to call modelBuilder.ConfigurePersistedGrantContext(_OperationalStoreOptions.Value); on ModelCreating as shown below
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int,
ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim,
ApplicationUserToken>,
IPersistedGrantDbContext
{
private readonly IOptions<OperationalStoreOptions> _OperationalStoreOptions;
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options)
{
this._OperationalStoreOptions = operationalStoreOptions;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseLazyLoadingProxies(true);
}
/// <summary>
/// Gets or sets the <see cref="DbSet{PersistedGrant}"/>.
/// </summary>
public DbSet<PersistedGrant> PersistedGrants { get; set; }
/// <summary>
/// Gets or sets the <see cref="DbSet{DeviceFlowCodes}"/>.
/// </summary>
public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }
/// <summary>
/// Gets or sets the <see cref="DbSet{Key}"/>.
/// </summary>
public DbSet<Key> Keys { get; set; }
Task<int> IPersistedGrantDbContext.SaveChangesAsync() => base.SaveChangesAsync();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ConfigurePersistedGrantContext(_OperationalStoreOptions.Value);
}
}
public class ApplicationUser : IdentityUser<int>
{
[Required]
public Guid ApplicationUserRecordId { get; set; }
}
public class ApplicationRole : IdentityRole<int>
{
public ApplicationRole()
{
}
public ApplicationRole(string roleName) : base(roleName)
{
}
}
public class ApplicationRoleClaim : IdentityRoleClaim<int>
{
}
public class ApplicationUserClaim : IdentityUserClaim<int>
{
}
public class ApplicationUserLogin : IdentityUserLogin<int>
{
}
public class ApplicationUserRole : IdentityUserRole<int>
{
}
public class ApplicationUserToken : IdentityUserToken<int>
{
}
Upvotes: 0
Reputation: 29976
For custom the user and role tables with ApiAuthorizationDbContext
, you could follow steps below:
Add User and Role Class
public class AppUser : IdentityUser<int>
{
}
public class AppRole : IdentityRole<int>
{
}
Add custom ApiAuthorizationDbContext
/// <summary>
/// Database abstraction for a combined <see cref="DbContext"/> using ASP.NET Identity and Identity Server.
/// </summary>
/// <typeparam name="TUser"></typeparam>
/// <typeparam name="TRole"></typeparam>
/// <typeparam name="TKey">Key of the IdentityUser entity</typeparam>
public class KeyApiAuthorizationDbContext<TUser, TRole, TKey> : IdentityDbContext<TUser, TRole, TKey>, IPersistedGrantDbContext
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
{
private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;
/// <summary>
/// Initializes a new instance of <see cref="ApiAuthorizationDbContext{TUser, TRole, TKey}"/>.
/// </summary>
/// <param name="options">The <see cref="DbContextOptions"/>.</param>
/// <param name="operationalStoreOptions">The <see cref="IOptions{OperationalStoreOptions}"/>.</param>
public KeyApiAuthorizationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions)
: base(options)
{
_operationalStoreOptions = operationalStoreOptions;
}
/// <summary>
/// Gets or sets the <see cref="DbSet{PersistedGrant}"/>.
/// </summary>
public DbSet<PersistedGrant> PersistedGrants { get; set; }
/// <summary>
/// Gets or sets the <see cref="DbSet{DeviceFlowCodes}"/>.
/// </summary>
public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }
Task<int> IPersistedGrantDbContext.SaveChangesAsync() => base.SaveChangesAsync();
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value);
}
}
/// <summary>
/// Database abstraction for a combined <see cref="DbContext"/> using ASP.NET Identity and Identity Server.
/// </summary>
/// <typeparam name="TUser"></typeparam>
public class ApiAuthorizationDbContext<TUser> : KeyApiAuthorizationDbContext<TUser, IdentityRole, string>
where TUser : IdentityUser
{
/// <summary>
/// Initializes a new instance of <see cref="ApiAuthorizationDbContext{TUser}"/>.
/// </summary>
/// <param name="options">The <see cref="DbContextOptions"/>.</param>
/// <param name="operationalStoreOptions">The <see cref="IOptions{OperationalStoreOptions}"/>.</param>
public ApiAuthorizationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions)
: base(options, operationalStoreOptions)
{
}
}
Change DbContext
public class ApplicationDbContext : KeyApiAuthorizationDbContext<AppUser, AppRole, int>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AppUser>(entity => { entity.ToTable(name: "User"); });
modelBuilder.Entity<AppRole>(entity => { entity.ToTable(name: "Role"); });
}
}
Register user and role
services.AddDefaultIdentity<AppUser>()
.AddRoles<AppRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<AppUser, ApplicationDbContext>();
Delete existing Migrations
(if database exist, you may need to delete it).
Run add-migration and update-database to check the result.
Currently, you need to custom ApiAuthorizationDbContext
, this issue has been tracked through ApiAuthorizationDbContext force TUser to extends IdentityUser instead of IdentityUser #9548 and Add IdentityUser support to ApiAuthorizationDbContext #13064. It will be some delay to get the neweast version.
Upvotes: 43