我想知道是否有更好的方法来做到这一点:
假设我有角色为 "SuperUser" 、 Admin 、 "Manager" 、 "Registered" 的用户。
在站点中注册的所有用户都具有“已注册”角色(例如,“经理”用户也具有“已注册”角色)。
现在我必须管理用户 Controller 上的 删除 操作。我想要达到的是:
所以我从以下代码开始:
[Authorize(Roles="Registered")]
public void Delete(int id)
{
string[] AllowedRoles = { "SuperAdmin", "Manager" };
if (_identity.FindFirst(ClaimTypes.UserData).Value == id.ToString())
{
//USER can delete himself!
//TO DO: Deletion code
}
else if (User.IsInAnyRole(AllowedRoles))
{
//CHECK IF I CAN DELETE THE GIVEN USER
}
}
我要做的是检查当前用户的每个角色与要删除的用户,但我真的不喜欢写很多“如果”....
有没有办法做得更好?
谢谢!
PS:不要担心 User.IsInAnyRole (这是一个自定义函数,用于验证用户是否处于指定角色之一。
最佳答案
我想知道,是否有未“注册”的经过身份验证的用户? IMO 这个角色不是必需的。如果您不同意,您可以修改下面的代码。
我不确定您的代码中的 _identity
和 User
是什么,但我假设 _identity
是 usermanager 存储库,而 User
是当前的 httpcontext 用户。我假设您需要 UserManager,因为如果不访问存储的声明(如 AspNetUserClaims),您将无法执行此测试。
请注意,我没有完全测试此代码。
// using System.Collections.Generic;
// using System.Linq;
// using System.Security.Claims;
// This method is available for all authenticated users
[Authorize]
public void Delete(int id)
{
// Test if current user wants to delete itself
if (User.FindFirst(ClaimTypes.UserData).Value != id.ToString())
{
// Find all roles of the current user.
var roles = User.FindAll("role").Select(r => r.Value).ToList();
// A fixed list, ordered by importance
var allowedRoles = new List<string> { "SuperAdmin", "Admin", "Manager" };
// Highest role of the current user
var role = allowedRoles.Intersect(roles).FirstOrDefault();
// "Registered" user is not allowed to do anything with other users
if (role == null)
return;
// Get the rolename(s) of the target user. Something like this, where
// _identity is a repository (usermanager?) that has access to the database
var targetUserRoles = _identity.Where(u => u.Id == id).Roles().Select(r => r.Name).ToList();
//var targetUserRoles = new List<string> { "Admin" };
// Highest role of the target user, because you don't want to delete
// a user that is both Manager and SuperAdmin when you are Admin.
var targetUserRole = allowedRoles.Intersect(targetUserRoles).FirstOrDefault();
// Users without a matching role may be deleted
if (targetUserRole != null)
{
// Determine the importance of the role of both
// the current user and the target user
var targetIndex = allowedRoles.IndexOf(targetUserRole);
var index = allowedRoles.IndexOf(role);
// Index==0 is SuperAdmin
// Otherwise index of role of targetuser must be higher
if (index > 0 && targetIndex <= index)
return;
}
}
// If we got here we can safely delete the user.
//TO DO: Deletion code
}
如果您想扩展层次结构,您只需将声明值添加到 allowedRoles 集合的适当位置。
关于c# - .NET MVC : Restrict action based on Role level,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58024581/