我要求应用程序根据用户代表的当前“客户”拥有不同的用户权限。一个用户可以连接到一个或多个客户。用户必须能够切换他想要操作的客户,并根据客户的选择获得正确的权限。这可以是某种下拉菜单或其他东西。
例如用户 Joe:
这可以用.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")]
这应该触发授权处理程序。
我不确定去这里的正确方法。有什么想法吗?
我通过以下方式实现了它:
创建包含您将在 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)]