我如何使用ASP.NET MVC Core初始设置角色和用户(如站点管理员)?

the*_*utz 1 c# asp.net-mvc asp.net-identity asp.net-core

虽然似乎有很多关于使用ASP.NET Core验证角色,声明等的文档,但是关于最初在我的应用程序中设置这些内容的信息很少.

the*_*utz 8

配置角色,声明等的最佳方法是在您的应用启动中.如果你知道自己在做什么,那么新的ASP.NET核心依赖注入可以让你轻松设置它.您的大多数工作都将发生在Startup.cs项目根目录的文件中.

1.设置用户秘密

不要通过将它们硬编码到可能共享的存储库中来与全世界共享新的用户机密.幸运的是,微软为此提供了一个很好的工具.本文详细解释了它:App Secrets的安全存储

要确保此服务稍后可用,请检查以下Startup构造函数方法Startup.cs:

public Startup(IHostingEnvironment env) {
    ...
    if (env.IsDevelopment()) {
        // BELOW IS THE IMPORTANT LINE
        builder.AddUserSecrets();
    }
    ...
    // This is important, too. It sets up a readonly property
    // that you can use to access your user secrets.
    Configuration = builder.Build();
}

// This is the read-only property
public IConfigurationRoot Configuration { get; }
Run Code Online (Sandbox Code Playgroud)

2.设置应用程序数据库

我正在为持久性存储使用Entity Framework Core.当我使用Web App模板创建应用程序时,会自动生成此代码.但我会在此处将其包含在内以供参考和排除故障(仍在Startup.cs):

public void ConfigureServices(IServiceCollection services)
{
    // My Db Context is named "ApplicationDbContext", which is the
    // default name. Yours might be something different.
    // Additionally, if you're using a persistence store other than
    // MSSQL Server, you might have a different set of options here.
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    // This sets up the basics of the Identity code. "ApplicationUser"
    // is the name of the model that I use for my basic user. It's simply
    // a POCO that can be modified like any EF model, and it's the default
    // name for a user in the template. "ApplicationRole" is a class that I
    // wrote that inherits from the "IdentityRole" base class. I use it to
    // add a role description, and any other future data I might want to
    // include with my role. I then tell the Identity code to store it's
    // data in the "ApplicationDbContext" that I just setup.
    services.AddIdentity<ApplicationUser, ApplicationRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProvider();

    // This sets up the MVC framework.
    services.AddMvc();
    ...
}
Run Code Online (Sandbox Code Playgroud)

3.在Configure方法中创建钩子

这是真正的工作开始的地方.您需要配置具有完全管理权限的角色,并为该角色分配第一个用户.我选择将该代码放在私有方法中Startup.cs,我在方法中调用Configure.一,调用代码:

// This method is not async out-of-the-box. Add the `async` modifier
// but keep the return type as `void`, since the signature needs to
// stay the same or you'll get a 500 error. We mark it as async because
// the Identity methods are mostly async methods.
public async void Configure(
    IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    ...
    // Default ASP.NET Core route (generated out of the box)
    // I've included this so you know where to put your code!
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

    // Her, we call the code that setups up our roles and our first user.
    // These are methods added to the `Startup` class. We use the
    // IApplicationBuilder variable to pass in a User and Role
    // Manager instance from the application services.
    await CreateRoles(
        app.ApplicationServices
            .GetRequiredService<RoleManager<ApplicationRole>>());
    await ConfigureSiteAdmin(
        app.ApplicationServices
            .GetRequiredService<RoleManager<ApplicationRole>>(),
        app.ApplicationServices
            .GetRequiredService<UserManager<ApplicationUser>>()
    );
}
Run Code Online (Sandbox Code Playgroud)

我发现设置一个存储我的角色名称的静态类很有用.这允许我在编译时检查名称,并在我需要在其他地方调用角色名时在整个代码中为我提供Intellisense帮助.它看起来像这样:

public static class RoleNames
{
    public const string SiteAdmin = "Site Admin";
    public const string CompanyAdmin = "Company Admin";
    ...
}
Run Code Online (Sandbox Code Playgroud)

4.设置你的角色

完成后,现在我们开始设置我们的角色.记住,我用作ApplicationUser我的用户类型和ApplicationRole我的角色类型.你可以用不同的名字命名.将这些方法添加到Startup.cs文件的底部:

private async Task CreateRoles(RoleManager<ApplicationRole> roleManager)
{
    var roles = new List<ApplicationRole>
    {
        // These are just the roles I made up. You can make your own!
        new ApplicationRole {Name = RoleName.SiteAdmin,
                             Description = "Full access to all features."},
        new ApplicationRole {Name = RoleName.CompanyAdmin,
                             Description = "Full access to features within their company."}
    };

    foreach (var role in roles)
    {
        if (await roleManager.RoleExistsAsync(role.Name)) continue;
        var result = await roleManager.CreateAsync(role);
        if (result.Succeeded) continue;

        // If we get here, something went wrong.
        throw new Exception($"Could not create '{role.Name}' role.");
    }
}
Run Code Online (Sandbox Code Playgroud)

5.创建新的超级用户

现在我们设置用于创建管理员的方法.我们检查以确保用户尚不存在.使用上面提到的dotnet用户机密存储用户名.我们还会检查以确保创建主要管理员角色,以便我们可以立即将此用户分配给该角色.

private async Task ConfigureSiteAdmin(
    RoleManager<ApplicationRole> roleManager,
    UserManager<ApplicationUser> userManager)
{
    if (await userManager.FindByEmailAsync(Configuration["SiteAdminEmail"]) != null)
        return;
    if (!await roleManager.RoleExistsAsync(RoleName.SiteAdmin))
        throw new Exception($"The {RoleName.SiteAdmin} role has not yet been created.");

    var user = new ApplicationUser
    {
        UserName = Configuration["SiteAdminEmail"],
        Email = Configuration["SiteAdminEmail"],
    };

    await userManager.CreateAsync(user, Configuration["SiteAdminPassword"]);
    await userManager.AddToRoleAsync(user, RoleName.SiteAdmin);
}
Run Code Online (Sandbox Code Playgroud)

6.享受!

我希望这对你有所帮助.我有一段时间在网络上散布所有这些信息.如果您有任何改进建议,请告诉我!