我有 SQL Server 表“用户”、“角色”和“安全组”,每个表都包含一个整数 ID 和一个 NVARCHAR 名称。我还有映射表 User_SecurityGroup 和 SecurityGroup_Role。一个用户可以属于多个安全组,一个安全组可以映射到多个角色。
我已经有一个获取用户角色列表的功能了。
public async Task<List<string>> GetUserRoles(string userId)
{
List<string> userRoles = new List<string>();
try
{
var securityGroupIds = db.User.FirstOrDefault(u => u.Id == userId).SecurityGroupIdList.ToList();
userRoles = db.SecurityGroupRole.Where(sgr => securityGroupIds.Contains(sgr.SecurityGroupId)).Select(sgr => sgr.RoleId).ToList();
}
catch (Exception ex)
{
throw ex;
}
return userRoles;
}
User.Identity.Name 已正确填充(我现在使用 Windows 身份验证)。我不知道如何配置 asp net core,以便当我放置像这样的
Authorize
属性时:
[Authorize(Roles = "SystemAdmin")]
在页面上,它运行我的函数来获取用户的角色列表,并检查在本例中 SystemAdmin 是否在其中。我不知道如何连接。
为了实现您的要求,您可以自定义
AuthorizationHandler
以使用 GetUserRoles
函数处理基于角色的授权。
定义自定义授权要求:
public class SystemAdminRequirement : IAuthorizationRequirement { }
创建自定义授权处理程序:
public class SystemAdminAuthorizationHandler : AuthorizationHandler<SystemAdminRequirement>
{
private readonly ApplicationDbContext db;
public SystemAdminAuthorizationHandler(ApplicationDbContext db)
{
this.db = db;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, SystemAdminRequirement requirement)
{
if (!context.User.Identity.IsAuthenticated)
{
context.Fail(); // User is not authenticated
return;
}
var userId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
var userRoles = await GetUserRoles(userId);
if (userRoles.Contains("SystemAdmin"))
{
context.Succeed(requirement); // User is authorized
}
else
{
context.Fail(); // User does not meet the requirement
}
}
public async Task<List<string>> GetUserRoles(string userId)
{
List<string> userRoles = new List<string>();
try
{
var securityGroupIds = db.User.FirstOrDefault(u => u.Id == userId).SecurityGroupIdList.ToList();
userRoles = db.SecurityGroupRole.Where(sgr => securityGroupIds.Contains(sgr.SecurityGroupId)).Select(sgr => sgr.RoleId).ToList();
}
catch (Exception ex)
{
throw ex;
}
return userRoles;
}
}
程序.cs:
builder.Services.AddIdentity<IdentityUser,IdentityRole>(options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<ApplicationDbContext>();
//Register your custom authorization handler
builder.Services.AddScoped<IAuthorizationHandler, SystemAdminAuthorizationHandler>();
//Define a policy ...
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("SystemAdminPolicy", policy =>
{
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new SystemAdminRequirement());
});
});
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();