web-dev-qa-db-ja.com

asp.netコア3.1アプリケーションにユーザーとロールをシードするにはどうすればよいですか?

IdentityDataContextクラスでprotected override void OnModelCreating(ModelBuilder builder)を使用して、このデータをシードする移行を作成してみました。

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
        const string ADMIN_ID = "b4280b6a-0613-4cbd-a9e6-f1701e926e73";
        const string ROLE_ID = ADMIN_ID;
        builder.Entity<IdentityRole>().HasData(new IdentityRole
        {
            Id = ROLE_ID,
            Name = "admin",
            NormalizedName = "ADMIN"
        });
        builder.Entity<MyIdentityUser>().HasData(new MyIdentityUser
        {
            Id = ADMIN_ID,
            UserName = "[email protected]",
            NormalizedUserName = "[email protected]",
            Email = "[email protected]",
            NormalizedEmail = "[email protected]",
            EmailConfirmed = true,
            PasswordHash = "AQABBAEABCcQAABAEBhd37krE/TyMklt3SIf2Q3ITj/dunHYr7O5Z9UB0R1+dpDbcrHWuTBr8Uh5WR+JrQ==",
            SecurityStamp = "VVPCRDAS3MJWQD5CSW2GWPRADBXEZINA",
            ConcurrencyStamp = "c8554266-b401-4519-9aeb-a9283053fc58"
        });
        builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>
        {
            RoleId = ROLE_ID,
            UserId = ADMIN_ID
        });
    }

これは機能しているようですが、Authorize atributeで装飾されたRazor Pageでエンドポイントにアクセスできません。データベースにこのすべてのデータがあるので奇妙です。このユーザーとしてログインすると、AspNetRolesテーブルに「admin」ロールがあることがわかります。 AspNetUserRolesテーブルで、ユーザーをロールに正しくマップしました。

[Authorize(Roles="admin")]
public class IndexModel : PageModel
{
    public async Task<IActionResult> OnGetAsync()
    {
        return Page();
    }

}

データベースによれば、管理者ロールを持つ上記のユーザーとしてログインすると、アクセス拒否ページにリダイレクトされます。

StartupクラスのConfigureメソッドでこのシードメソッドを実行しようとする人がいるのを見ましたが、RoleManagerとUserManagerでこれを実行しようとすると、依存関係の注入で問題が発生します。

System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]' has been registered.

3
Tomasz Sikora

私はほとんどそこにいた。最初は明白ではありませんでしたが、IdentityHostingStartup.csファイルのConfigureメソッドに.AddRoles<IdentityRole>()行を追加する必要がありました。

これは、asp.net core 3.1ドキュメントのロールベースの承認ページの最後に記載されています: ドキュメントへのリンク

_public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddRoles<IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
    services.AddRazorPages();
}
_

役割はすでに考慮されており、この機能を明示的に追加する必要がないと思いました。

ページの上部に、役割ベースの承認を追加するために.AddRoles<IdentityRole>()をConfigureメソッドに追加する必要があることを明記する必要があります。代わりに、Authorization属性の多くの組み合わせが表示され、下部に「Identityに役割サービスを追加」という短い段落があり、これがすべてを機能させるものであるという説明はありません。

1
Tomasz Sikora