如何基于角色向Razor Pages应用添加身份?

时间:2019-04-22 15:03:36

标签: c# asp.net-mvc identity roles razor-pages

我正在设置一个新的Razor Pages应用,我想添加基于角色的授权。网上有很多教程如何使用ASP.NET MVC应用程序执行此操作,而不是Razor页面。我尝试了几种解决方案,但对我没有任何帮助。目前,我有一个问题,如何为db分配角色,并将此角色添加到每个新注册用户。

这是我的Startup.cs的样子:

public async Task ConfigureServices(IServiceCollection services)
{
        var serviceProvider = services.BuildServiceProvider();

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
        });

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(config =>
        {
            config.SignIn.RequireConfirmedEmail = true;
        })
            .AddRoles<IdentityRole>()
            .AddDefaultUI(UIFramework.Bootstrap4)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddAuthorization(config =>
        {
            config.AddPolicy("RequireAdministratorRole",
                policy => policy.RequireRole("Administrator"));
        });

        services.AddTransient<IEmailSender, EmailSender>();
        services.Configure<AuthMessageSenderOptions>(Configuration);

        services.AddRazorPages()
            .AddNewtonsoftJson()
            .AddRazorPagesOptions(options => {
                options.Conventions.AuthorizePage("/Privacy", "Administrator");
            });

        await CreateRolesAsync(serviceProvider);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseCookiePolicy();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }

    /// <summary>
    /// Method that creates roles
    /// </summary>
    /// <param name="serviceProvider"></param>
    /// <returns></returns>
    private async Task CreateRolesAsync(IServiceProvider serviceProvider)
    {
        //adding custom roles
        var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        string[] roleNames = { "Admin", "Member", "Outcast" };
        IdentityResult roleResult;

        foreach (var roleName in roleNames)
        {
            //creating the roles and seeding them to the database
            var roleExist = await RoleManager.RoleExistsAsync(roleName);
            if (!roleExist)
            {
                roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
            }
        }
}

现在此代码引发了异常:

  

System.InvalidOperationException:'无法找到所需的服务。请通过在应用程序启动代码中对“ ConfigureServices(...)”的调用内调用“ IServiceCollection.AddAuthorizationPolicyEvaluator”来添加所有必需的服务。

添加AddAuthorizationPolicyEvaluator并没有任何改变。

有什么提示吗?

1 个答案:

答案 0 :(得分:0)

好吧,我只是让我的应用正常运行:)我想我只是将我的x代码发布在这里,以解决以后的问题-也许会对某人有所帮助。

Startup.cs

通常,启动时应用程序只是创建新数据库,添加“ Admin”,“ Member”和“ Outcast”角色,最后根据用户机密凭据创建superUser帐户。 在public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; }); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<IdentityUser>(config => { config.SignIn.RequireConfirmedEmail = true; }) .AddRoles<IdentityRole>() .AddDefaultUI(UIFramework.Bootstrap4) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddAuthorization(config => { config.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator")); config.AddPolicy("RequireMemberRole", policy => policy.RequireRole("Member")); }); services.AddTransient<IEmailSender, EmailSender>(); services.Configure<AuthMessageSenderOptions>(Configuration); services.AddRazorPages() .AddNewtonsoftJson() .AddRazorPagesOptions(options => { options.Conventions.AuthorizePage("/Privacy", "RequireAdministratorRole"); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, UserManager<IdentityUser> userManager) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); CreateDatabase(app); CreateRolesAsync(serviceProvider).Wait(); CreateSuperUser(userManager).Wait(); } private async Task CreateSuperUser(UserManager<IdentityUser> userManager) { var superUser = new IdentityUser { UserName = Configuration["SuperUserLogin"], Email = Configuration["SuperUserLogin"] }; await userManager.CreateAsync(superUser, Configuration["SuperUserPassword"]); var token = await userManager.GenerateEmailConfirmationTokenAsync(superUser); await userManager.ConfirmEmailAsync(superUser, token); await userManager.AddToRoleAsync(superUser, "Admin"); } private void CreateDatabase(IApplicationBuilder app) { using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) { var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); context.Database.EnsureCreated(); } } private async Task CreateRolesAsync(IServiceProvider serviceProvider) { //adding custom roles var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>(); string[] roleNames = { "Admin", "Member", "Outcast" }; IdentityResult roleResult; foreach (var roleName in roleNames) { //creating the roles and seeding them to the database var roleExist = await RoleManager.RoleExistsAsync(roleName); if (!roleExist) { roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName)); } } } } 文件中,我还有一行代码将默认角色“成员”添加到新成员中

Register.cshtml.cs