如何将基于角色的身份添加到 Razor Pages 应用程序?

我正在设置一个新的 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);

    }

    }


现在这段代码抛出了一个异常:


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


添加AddAuthorizationPolicyEvaluator没有任何改变。


有小费吗?


繁星淼淼
浏览 94回答 1
1回答

弑天下

好的,我只是让我的应用程序正常工作 :) 我想我只是在这里发布我的Startup.cs代码以备将来使用 - 也许它会对某人有所帮助。public class Startup{&nbsp; &nbsp; public Startup(IConfiguration configuration)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Configuration = configuration;&nbsp; &nbsp; }&nbsp; &nbsp; public IConfiguration Configuration { get; }&nbsp; &nbsp; // This method gets called by the runtime. Use this method to add services to the container.&nbsp; &nbsp; public void ConfigureServices(IServiceCollection services)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; services.Configure<CookiePolicyOptions>(options =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // This lambda determines whether user consent for non-essential cookies is needed for a given request.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.CheckConsentNeeded = context => true;&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; services.AddDbContext<ApplicationDbContext>(options =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.UseSqlServer(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Configuration.GetConnectionString("DefaultConnection")));&nbsp; &nbsp; &nbsp; &nbsp; services.AddDefaultIdentity<IdentityUser>(config =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; config.SignIn.RequireConfirmedEmail = true;&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddRoles<IdentityRole>()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddDefaultUI(UIFramework.Bootstrap4)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddEntityFrameworkStores<ApplicationDbContext>();&nbsp; &nbsp; &nbsp; &nbsp; services.AddAuthorization(config =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; config.AddPolicy("RequireAdministratorRole",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; policy => policy.RequireRole("Administrator"));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; config.AddPolicy("RequireMemberRole",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; policy => policy.RequireRole("Member"));&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; services.AddTransient<IEmailSender, EmailSender>();&nbsp; &nbsp; &nbsp; &nbsp; services.Configure<AuthMessageSenderOptions>(Configuration);&nbsp; &nbsp; &nbsp; &nbsp; services.AddRazorPages()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddNewtonsoftJson()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .AddRazorPagesOptions(options => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.Conventions.AuthorizePage("/Privacy", "RequireAdministratorRole");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }&nbsp; &nbsp; // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.&nbsp; &nbsp; public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, UserManager<IdentityUser> userManager)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (env.IsDevelopment())&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseDeveloperExceptionPage();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseDatabaseErrorPage();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseExceptionHandler("/Error");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; app.UseHsts();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; app.UseHttpsRedirection();&nbsp; &nbsp; &nbsp; &nbsp; app.UseStaticFiles();&nbsp; &nbsp; &nbsp; &nbsp; app.UseCookiePolicy();&nbsp; &nbsp; &nbsp; &nbsp; app.UseRouting();&nbsp; &nbsp; &nbsp; &nbsp; app.UseAuthentication();&nbsp; &nbsp; &nbsp; &nbsp; app.UseAuthorization();&nbsp; &nbsp; &nbsp; &nbsp; app.UseEndpoints(endpoints =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endpoints.MapRazorPages();&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; CreateDatabase(app);&nbsp; &nbsp; &nbsp; &nbsp; CreateRolesAsync(serviceProvider).Wait();&nbsp; &nbsp; &nbsp; &nbsp; CreateSuperUser(userManager).Wait();&nbsp; &nbsp; }&nbsp; &nbsp; private async Task CreateSuperUser(UserManager<IdentityUser> userManager)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var superUser = new IdentityUser { UserName = Configuration["SuperUserLogin"], Email = Configuration["SuperUserLogin"] };&nbsp; &nbsp; &nbsp; &nbsp; await userManager.CreateAsync(superUser, Configuration["SuperUserPassword"]);&nbsp; &nbsp; &nbsp; &nbsp; var token = await userManager.GenerateEmailConfirmationTokenAsync(superUser);&nbsp; &nbsp; &nbsp; &nbsp; await userManager.ConfirmEmailAsync(superUser, token);&nbsp; &nbsp; &nbsp; &nbsp; await userManager.AddToRoleAsync(superUser, "Admin");&nbsp; &nbsp; }&nbsp; &nbsp; private void CreateDatabase(IApplicationBuilder app)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.Database.EnsureCreated();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private async Task CreateRolesAsync(IServiceProvider serviceProvider)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; //adding custom roles&nbsp; &nbsp; &nbsp; &nbsp; var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();&nbsp; &nbsp; &nbsp; &nbsp; string[] roleNames = { "Admin", "Member", "Outcast" };&nbsp; &nbsp; &nbsp; &nbsp; IdentityResult roleResult;&nbsp; &nbsp; &nbsp; &nbsp; foreach (var roleName in roleNames)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //creating the roles and seeding them to the database&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var roleExist = await RoleManager.RoleExistsAsync(roleName);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!roleExist)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}通常,应用程序在启动时只是创建新数据库,添加“Admin”、“Member”和“Outcast”角色,最后根据用户机密凭据创建超级用户帐户。另外在Register.cshtml.cs文件中我有一行将默认角色“成员”添加到新成员&nbsp; &nbsp; public async Task<IActionResult> OnPostAsync(string returnUrl = null)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; returnUrl = returnUrl ?? Url.Content("~/");&nbsp; &nbsp; &nbsp; &nbsp; if (ModelState.IsValid)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var result = await _userManager.CreateAsync(user, Input.Password);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (result.Succeeded)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _logger.LogInformation("User created a new account with password.");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await _userManager.AddToRoleAsync(user, "Member");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var callbackUrl = Url.Page(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "/Account/ConfirmEmail",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pageHandler: null,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; values: new { userId = user.Id, code = code },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protocol: Request.Scheme);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await _emailSender.SendEmailAsync(Input.Email, "Confirm your email to get acces to Functionality Matrix pages",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Block autologin after registration&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //await _signInManager.SignInAsync(user, isPersistent: false);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Redirect("./ConfirmEmailInfo");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (var error in result.Errors)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ModelState.AddModelError(string.Empty, error.Description);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // If we got this far, something failed, redisplay form&nbsp; &nbsp; &nbsp; &nbsp; return Page();&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript