Blazor WASM 身份验证以及 Blazor 服务器身份验证

时间:2021-01-27 05:29:26

标签: authentication authorization visual-studio-2019 blazor blazor-client-side

使用 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)
        {
        }
    }

我怎样才能让它发挥作用?

感谢任何参考:)

1 个答案:

答案 0 :(得分:0)

您能分享您服务器的 Startup.cs 文件吗?特别是在您为 Identity/DbContexts 注册/配置服务的地方。 IdentityDbContextApiAuthorizationDbContext 基本相同,但它为持久授权和设备流代码添加了所需的 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();