【问题标题】:AspNetCore 3.1 Role Policies not working on views controllerAspNetCore 3.1 角色策略不适用于视图控制器
【发布时间】:2021-04-25 06:01:36
【问题描述】:

我已经在我的项目中实现了 Identity Scaffold,而身份验证就像一个魅力,我观看了一些关于如何使用 Identity 实现角色的教程,但我很难使用控制器上的角色策略标签。

他们都告诉我我没有被授权。

这是我的startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    public IConfiguration Configuration { get; }
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseMySql(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddIdentity<IdentityUser, IdentityRole>(options => 
            options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddIdentityCore<ApplicationUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultUI();           
        services.AddAuthorization(options =>
        {
            options.AddPolicy("AdminAccess", policy => policy.RequireRole("Admin"));

            options.AddPolicy("ManagerAccess", policy =>
                policy.RequireAssertion(context =>
                            context.User.IsInRole("Admin")
                            || context.User.IsInRole("Manager")));

            options.AddPolicy("UserAccess", policy =>
                policy.RequireAssertion(context =>
                            context.User.IsInRole("Admin")
                            || context.User.IsInRole("Manager")
                            || context.User.IsInRole("User")));
        });

        services.AddTransient<IEmailSender, EmailSender>(i =>
            new EmailSender(
                Configuration["EmailSender:Host"],
                Configuration.GetValue<int>("EmailSender:Port"),
                Configuration.GetValue<bool>("EmailSender:EnableSSL"),
                Configuration["EmailSender:UserName"],
                Configuration["EmialSender:Password"]
            )
        );             
        services.AddControllers().AddNewtonsoftJson(options =>
            options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );
        services.AddControllersWithViews();
        services.AddRazorPages().AddRazorRuntimeCompilation();
    }
    // 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("/Home/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.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Charts}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

我有一个 PolicyController.cs

public class PolicyController : Controller
{
    public IActionResult Index() => View();

    [Authorize(Policy = "UserAccess")]
    public IActionResult UserPage() => View();

    [Authorize(Policy = "ManagerAccess")]
    public IActionResult ManagerPage() => View();

    //[Authorize(Policy = "AdminAccess")]
    public IActionResult AdminPage()
    {
        // This returns FALSE
        if (User.IsInRole("Admin"))
            ViewBag.Message = "You Admin";
        ViewBag.Message = "No Admin";
        return View();
    }
}

我还有一个视图,我在其中创建角色并将它们链接到用户,我什至在我的数据库中查找,我看到 RoleID 和在 aspnet-user-roles 表上创建的 UserID 但我无法获得在那些具有我创建的角色的测试视图上,这些角色的类型与 startup.cs 中的完全相同

[HttpPost]
public async Task<IActionResult> UpdateUserRole(UpdateUserRoleViewModel vm)
{
    var user = await _userManager.FindByEmailAsync(vm.UserEmail);

    if (vm.Delete)
        await _userManager.RemoveFromRoleAsync(user, vm.Role);
    else
        await _userManager.AddToRoleAsync(user, vm.Role);

    return RedirectToAction("Index");
}

我做错了什么?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc asp.net-core-identity


    【解决方案1】:
      services.AddIdentity<IdentityUser, IdentityRole>(options => 
            options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddIdentityCore<ApplicationUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultUI();
    

    可能问题和上面的代码有关,从代码上看,好像是想在 AspNetUsers 表中添加自定义用户数据。因此,您将创建一个ApplicationUser.cs 类并从IdentityUser 继承,代码如下:

    public class ApplicationUser: IdentityUser
    {
        //custom user data.
        public string CustomTag { get; set; }
    }
    

    然后,在Startup.ConfigureServices中,我们可以将IdentityUser替换为ApplicationUser,并使用以下代码配置Identity:

            services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
                     .AddEntityFrameworkStores<ApplicationDbContext>()
                     .AddDefaultTokenProviders()
                     .AddDefaultUI();
    
            //there is no need to add the following code:
            //services.AddIdentityCore<ApplicationUser>()
            //    .AddEntityFrameworkStores<ApplicationDbContext>()
            //    .AddDefaultUI();
    

    [注意]通过使用上述代码,对于所有 Scaffolding Identity razor 页面,您可能还需要将 IdentityUser 替换为 ApplicationUser

    如果您不想通过 ApplicationUser 类将自定义用户数据添加到 AspNetUsers 表中,请尝试删除以下代码:

            //services.AddIdentityCore<ApplicationUser>()
            //    .AddEntityFrameworkStores<ApplicationDbContext>()
            //    .AddDefaultUI();
    

    另外,如果还是不行,请重新检查数据库,是否使用正确的数据库,并检查AspNetUsersAspNetRolesAspNetUserRoles表中的用户角色。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多