.NET根据当前客户识别不同的权限

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

我要求应用程序根据用户代表的当前“客户”拥有不同的用户权限。一个用户可以连接到一个或多个客户。用户必须能够切换他想要操作的客户,并根据客户的选择获得正确的权限。这可以是某种下拉菜单或其他东西。

例如用户 Joe:

  • 对于客户 X,他拥有 Products.Create 权限
  • 对于客户 Y,他拥有 Products.View 权限

这可以用.NET身份来实现吗?

我正在考虑创建一些自定义表格,例如。

[表用户客户权限]

UserId, PermissionValue, CustomerId

然后实现一个自定义

AuthorizationHandler
,它应该检查用户对当前处于活动状态的客户拥有什么权限值。活跃客户可能来自像
?customerId=CustomerX
这样的查询字符串或
Session
中的查询字符串,或者我认为来自数据库。

授权处理程序可能看起来像这样

protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { if(customIdStr != null)
{
    var currentUser = await _userManager.GetUserAsync(context.User);
    var customIdStr = httpContext.Request.Query["customerId"].FirstOrDefault();
    var userOperatorRoles = _dbContext.OperatorRoles
                .Where(u => u.OperatorId == currentUser.Id && u.roleId == requirement.Permission && u.customerId == customIdStr)
                .ToList();//.ToList();
            
    if (userOperatorRoles.Any())
    {
        context.Succeed(requirement);
        return;
    }
}

然后我可以在我的动作上放置

[Authorize]
属性,例如

 [Authorize(Policy = "Permissions.Products.View")]

这应该触发授权处理程序。

我不确定去这里的正确方法。有什么想法吗?

c# asp.net-core asp.net-identity
1个回答
0
投票

我通过以下方式实现了它:

创建包含您将在 Authorize 属性

AuthRolesPolicy.cs

中使用的角色规则的类
public static class AuthRolesPolicy
{
    public const string Admin = "ADMIN";
    public const string View = "USER";

    public static readonly string[] UserLevel = { Admin, User};
    public static readonly string[] AdminLevel = { Admin};
}

因为管理员可以看到用户的所有内容,所以您将需要下一个帮助者

RoleRequirement .cs

public class RoleRequirement : IAuthorizationRequirement
{
    public string[] Roles { get; }

    public RoleRequirement(string[] roles)
    {
        Roles = roles;
    }
}

现在我们准备创建授权处理程序

MyAuthorizationHandler.cs

public class MyAuthorizationHandler : AuthorizationHandler<RoleRequirement>, IAuthorizationRequirement
{
    private readonly IYourService _databaseService;

    public PortalAuthorizationHandler(IYourService databaseService)
    {
        _databaseService = databaseService;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirement requirement)
    {
        try
        {
            // Read user identities from authentication step
            var userId = UserClaimsReader.GetUserId(context.User);
            if (!string.IsNullOrEmpty(userId))
            {
                // Get user information from DB
                var user = await _databaseService.ReadUserCreds(userId);

                if (user != null)
                {
                    // Check is user role valid based on Policy level
                    bool isRoleValid = requirement.Roles.Contains(user.Role);

                    if (isRoleValid)
                    {
                        context.Succeed(requirement);
                        return;
                    }
                }
            }
        }
        catch (Exception ex)
        {                
        }
        
        context.Fail();
        return;
    }
}

终于可以更新了

Program.cs

...
builder.Services.AddScoped<IAuthorizationHandler, MyAuthorizationHandler>();
...
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy(AuthRolesPolicy.Admin, policy => policy.Requirements.Add(new RoleRequirement(AuthRolesPolicy.AdminLevel)));
    options.AddPolicy(AuthRolesPolicy.User, policy => policy.Requirements.Add(new RoleRequirement(AuthRolesPolicy.UserLevel)));
});
...

现在您可以在控制器中使用

[Authorize(Policy = AuthorizationRolesPolicy.Admin)]

© www.soinside.com 2019 - 2024. All rights reserved.