该应用程序是在asp.net core 3上开发的。当用户担任多个角色时,面临授权问题。
用户角色:
public enum UserRole
{
None = 0x0,
View = 0x1,
ConfirmAlarm = 0x2,
ObjectScaling = 0x4,
SchemeEditor = 0x8,
ObjectEditor = 0x10
}
索赔
private async Task Authenticate(User user)
{
var claims = new List<Claim>
{
new Claim(ClaimsIdentity.DefaultNameClaimType, user.Login),
new Claim(ClaimsIdentity.DefaultRoleClaimType, ((UserRole)user.Role).ToString()),
new Claim("uGroupId", user.GroupId.ToString()),
new Claim("uInfo", user.Info),
new Claim("uTheme", user.Theme)
};
ClaimsIdentity id = new ClaimsIdentity(claims, "ApplicationCookie",
ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new
ClaimsPrincipal(id));
}
控制器方法:
[Authorize(Roles = "View")]
[HttpPost("[action]")]
public async Task<string> SomeAction()
{
//...some code
}
如果用户具有“查看,ConfirmAlarm,ObjectScaling,SchemeEditor,ObjectEditor”的所有角色,则无法在控制器中对该用户授权该方法。
可能是什么问题?是否需要创建自定义AuthorizeAttribute?
更新
添加了两个类: RolesRequirement.cs
public class RolesRequirement : IAuthorizationRequirement
{
public string RoleName { get; }
public RolesRequirement(string roleName)
{
RoleName = roleName;
}
}
RoleHandler.cs
public class RoleHandler : AuthorizationHandler<RolesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesRequirement requirement)
{
string roles = context.User.Claims.FirstOrDefault(x => x.Type == ClaimsIdentity.DefaultRoleClaimType).Value;
if (!string.IsNullOrEmpty(roles))
{
if (roles.Contains(requirement.RoleName))
{
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
将策略添加到startup.cs
services.AddAuthorization(options =>
{
options.AddPolicy("View", policy => policy.Requirements.Add(new RolesRequirement("View")));
options.AddPolicy("ConfirmAlarm", policy => policy.Requirements.Add(new RolesRequirement("ConfirmAlarm")));
options.AddPolicy("ObjectEditor", policy => policy.Requirements.Add(new RolesRequirement("ObjectEditor")));
});
并在控制器方法之前添加属性。
[Authorize(Policy = "View")]
[Authorize(Policy = "ObjectEditor")]
[HttpPost("[action]")]
public async Task<string> SomeAction()
{
//...some code
}
答案 0 :(得分:1)
请尝试以下行:
ClaimsIdentity id = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme,
ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
代替:
ClaimsIdentity id = new ClaimsIdentity(claims, "ApplicationCookie",
ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
CookieAuthenticationDefaults.AuthenticationScheme
是Cookies
,它与Startup.cs
中cookie的默认authenticationScheme匹配:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
已更新:
您可以手动检查索赔:
services.AddAuthorization(options =>
{
options.AddPolicy("AllowedView", policy =>
{
policy.RequireAssertion(context =>
{
var roles = context.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value;
var listRolesElements = roles.Split(',').ToList();
return listRolesElements.Contains("View");
});
});
});
并在需要View
权限的控制器上应用策略:
[Authorize(Policy = "AllowedView")]