如何配置 asp net core 授权以从我的自定义数据库架构中查找用户的角色?

问题描述 投票:0回答:1

我有 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 是否在其中。我不知道如何连接。

asp.net-core entity-framework-core asp.net-identity
1个回答
0
投票

为了实现您的要求,您可以自定义

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();
© www.soinside.com 2019 - 2024. All rights reserved.