目前,我正在一个项目管理网站上。系统中有一个SuperAdmin(角色),可以创建新项目。 SuperAdmin可以将用户分配给具有不同角色的这些项目,例如admin或观察者。用户可以为不同的项目扮演不同的角色,甚至根本没有任何角色。
例如:
“身份”似乎不支持这种行为。基于声明的授权似乎支持静态声明,但不支持动态声明(访问具有ID的项目)。 我可以创建自己的UserProjectRoles类,该类将用户,项目和角色关联在一起,并在授权处理程序(基于策略的授权)中使用该类,但是我想知道这是否是正确的解决方案。您将如何解决此任务?
编辑:
我最终完成了以下操作:我创建了一个新的UserProjectClaims表,该表连接了Users和Projects,并将角色类型包含为枚举(我将角色/声明类型移到它自己的表中,这只是为了为了测试)。
public class UserProjectClaim
{
public int ProjectId { get; set; }
public Project Project { get; set; }
public int UserId { get; set; }
public AppUser User { get; set; }
public UserProjectClaimEnum ClaimType { get; set; }
}
然后,如基于策略的授权教程中所见,我在AuthorizationHandler中使用了该表:
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ProjectAdminRequirement requirement)
{
if (context.Resource is AuthorizationFilterContext authContext)
{
var projectId = Int32.Parse(authContext.HttpContext.Request.Query["projectId"]);
var userid = (await _userManager.GetUserAsync(context.User)).Id;
var claim = _dbContext.AppUsers.Include(i=>i.UserProjectClaims).Single(u=>u.Id==userid).UserProjectClaims.SingleOrDefault(p => p.ProjectId == projectId);
if (claim != null && claim.ClaimType == Data.Enums.UserProjectClaimEnum.ProjectAdmin)
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
}
它按预期工作。
答案 0 :(得分:1)
在使用个人用户帐户(VS2017)创建新的Web应用程序(MVC)之后,您会发现诸如AspNetRoles,AspNetRoleClaims,AspNetUserRoles,AspNetUserClaims之类的表作为实体框架核心IdentityContext的一部分。
AccountController注入了一个UserManager,但是没有维护Roles&Claims的方法。没有提供开箱即用的视图(页面),控制器和模型来管理关系。
好消息是UserManager具有各种功能,可以向用户添加声明和角色。 AddClaimAsync,AddToRoleAsync,GetClaimsAsync,GetRolesAsync,GetUsersForClaimAsync,GetUsersInRoleAsync,RemoveClaimAsync,RemoveFromRoleAsync以及将声明/角色作为IEnumerable处理的版本。
短期解决方案:向AccountController或ManageController添加方法,甚至创建RolesController来支持管理这些关系的页面,都不是一件容易的事。
长期解决方案:了解如何在创建新的MVC Identity项目时添加模板以生成这些项目。然后通过在GitHub上公开它来炫耀一下:)或写一篇关于您在所处情况下向其他人学到的东西的文章。
后记:通过创建一个放置在请求处理路径中的中间件,您可以为当前用户加载其余请求可以引用的角色/声明。从Projects到Roles的联接表(可能具有读取角色和写入角色),您可以将所需的角色与用户拥有的角色/声明进行比较。
技术:Here是自定义策略和授权的绝佳解释。对于您的情况,该策略将测试用户是否具有与您的项目匹配的角色/声明。您在上面的角色实际上是Project-Read,Project-Write。如果没有,则无法访问。