【问题标题】:How to add identity based on roles to Razor Pages app?如何将基于角色的身份添加到 Razor Pages 应用程序?
【发布时间】:2019-09-11 18:30:34
【问题描述】:

我正在设置一个新的 Razor Pages 应用程序,并且我想添加基于角色的授权。网络上有很多教程如何使用 ASP.NET MVC 应用程序而不是 Razor 页面。我尝试了一些解决方案,但对我没有任何效果。目前我有一个问题,如何使用角色播种数据库并将此角色添加到每个新注册用户。

这就是我的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 没有任何改变。

有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    好的,我只是让我的应用程序正常运行 :) 我想我只是在这里发布我的 Startup.cs 代码以备将来的问题 - 也许它会对某人有所帮助。

    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));
                }
            }
        }
    }
    

    通常应用程序在启动时只是创建新数据库,添加“Admin”、“Member”和“Outcast”角色,最后根据用户秘密凭据创建超级用户帐户。 另外在Register.cshtml.cs 文件中,我有一行将默认角色“成员”添加到新成员

        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            if (ModelState.IsValid)
            {
                var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
                var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User created a new account with password.");
    
    
    
                    await _userManager.AddToRoleAsync(user, "Member");
    
    
    
                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { userId = user.Id, code = code },
                        protocol: Request.Scheme);
    
                    await _emailSender.SendEmailAsync(Input.Email, "Confirm your email to get acces to Functionality Matrix pages",
                        $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
    
                    // Block autologin after registration
                    //await _signInManager.SignInAsync(user, isPersistent: false);
                    return Redirect("./ConfirmEmailInfo");
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }
    
            // If we got this far, something failed, redisplay form
            return Page();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-10
      • 2015-06-28
      • 2020-03-04
      • 2015-06-04
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 2021-03-31
      • 2019-11-15
      相关资源
      最近更新 更多