使用 ApiAuthorizationDbContext 时,WASM 获取页面会进行身份验证并传递令牌,但 Razor 页面不会进行身份验证。当切换到 IdentityDbContext 时,会发生相反的情况,我能够对 razor 页面进行身份验证,但 WASM 提取页面将不会进行身份验证。我在 https://github.com/williameduardo79/BlazorServerClientSample
有一个非常简单的示例这适用于 Blazor WASM
public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
}
这适用于 Blazor 页面
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
我怎样才能让它发挥作用?
感谢任何参考:)
答案 0 :(得分:0)
您能分享您服务器的 Startup.cs
文件吗?特别是在您为 Identity/DbContexts 注册/配置服务的地方。 IdentityDbContext
与 ApiAuthorizationDbContext
基本相同,但它为持久授权和设备流代码添加了所需的 DbSets
,以启用基于 API 的身份验证。
我有一个适用于 MVC Razor 页面和 Blazor WASM 的 IdentityDbContext
,所以我知道这是可能的! :) 不同之处在于我明确地实现了类型:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string,
IdentityUserClaim<string>, ApplicationUserRole, IdentityUserLogin<string>, IdentityRoleClaim<string>,
IdentityUserToken<string>>, IPersistedGrantDbContext
{
private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;
public ApplicationDbContext(DbContextOptions options, IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options)
{
_operationalStoreOptions = operationalStoreOptions;
}
public DbSet<ApplicationUser> ApplicationUser { get; set; }
public DbSet<PersistedGrant> PersistedGrants { get; set; }
public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }
Task<int> IPersistedGrantDbContext.SaveChangesAsync() => base.SaveChangesAsync();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value);
// Override default AspNet Identity table names
modelBuilder.Entity<ApplicationUser>().Property(x => x.Created).HasDefaultValueSql("getdate()");
modelBuilder.Entity<ApplicationUser>(entity => { entity.ToTable(name: "Users"); });
modelBuilder.Entity<ApplicationRole>(entity => { entity.ToTable(name: "Roles"); });
modelBuilder.Entity<DeviceFlowCodes>(entity => { entity.ToTable("UserDeviceCodes"); });
modelBuilder.Entity<PersistedGrant>(entity => { entity.ToTable("UserPersistedGrants"); });
modelBuilder.Entity<ApplicationUserRole>(entity =>
{
entity.ToTable("UserRoles");
entity.HasKey(x => new { x.UserId, x.RoleId });
entity.HasOne(ur => ur.Role)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
entity.HasOne(ur => ur.User)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
modelBuilder.Entity<IdentityUserClaim<string>>(entity => { entity.ToTable("UserClaims"); });
modelBuilder.Entity<IdentityUserLogin<string>>(entity => { entity.ToTable("UserLogins"); });
modelBuilder.Entity<IdentityUserToken<string>>(entity => { entity.ToTable("UserTokens"); });
modelBuilder.Entity<IdentityRoleClaim<string>>(entity => { entity.ToTable("RoleClaims"); });
}
}
在我的 Startup.cs
文件中:
// ASP.NET Identity
services.AddDefaultIdentity<ApplicationUser>(options =>
{
options.User.RequireUniqueEmail = true;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
})
.AddRoles<ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
// Identity Server
var identityServerBuilder = services.AddIdentityServer(options =>
{
options.Authentication.CookieSlidingExpiration = true;
options.Authentication.CookieLifetime = TimeSpan.FromDays(7);
}).AddAspNetIdentity<ApplicationUser>()
.AddOperationalStore<ApplicationDbContext>()
.AddIdentityResources()
.AddApiResources()
.AddClients();