AspNetCore 3.1 角色策略不适用于视图控制器
AspNetCore 3.1 Role Policies not working on views controller
我已经在我的项目中实施了身份支架,并且身份验证非常有效,我观看了一些有关如何使用身份实施角色的教程,但我很难使用控制器上的角色策略标签。
他们都说我没有被授权。
这是我的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();
}
}
我也有一个视图,我在其中创建角色并将它们 link 给用户,我什至查找我的数据库,我看到 RoleID 和在 aspnet-user-roles [=29 上创建的 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");
}
我做错了什么?
services.AddIdentity<IdentityUser, IdentityRole>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityCore<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI();
可能问题与上述代码有关,从代码来看,你似乎想要将自定义用户数据添加到 AspNetUsers table。因此,您将创建一个 ApplicationUser.cs
class 并继承自 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 class 将自定义用户数据添加到 AspNetUsers table,请尝试删除以下代码:
//services.AddIdentityCore<ApplicationUser>()
// .AddEntityFrameworkStores<ApplicationDbContext>()
// .AddDefaultUI();
此外,如果仍然无法正常工作,请重新检查数据库,是否使用了正确的数据库,并从 AspNetUsers
、AspNetRoles
和 AspNetUserRoles
table.
我已经在我的项目中实施了身份支架,并且身份验证非常有效,我观看了一些有关如何使用身份实施角色的教程,但我很难使用控制器上的角色策略标签。
他们都说我没有被授权。
这是我的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();
}
}
我也有一个视图,我在其中创建角色并将它们 link 给用户,我什至查找我的数据库,我看到 RoleID 和在 aspnet-user-roles [=29 上创建的 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");
}
我做错了什么?
services.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddIdentityCore<ApplicationUser>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultUI();
可能问题与上述代码有关,从代码来看,你似乎想要将自定义用户数据添加到 AspNetUsers table。因此,您将创建一个 ApplicationUser.cs
class 并继承自 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 class 将自定义用户数据添加到 AspNetUsers table,请尝试删除以下代码:
//services.AddIdentityCore<ApplicationUser>()
// .AddEntityFrameworkStores<ApplicationDbContext>()
// .AddDefaultUI();
此外,如果仍然无法正常工作,请重新检查数据库,是否使用了正确的数据库,并从 AspNetUsers
、AspNetRoles
和 AspNetUserRoles
table.