我想知道是否有更好的方法: 假设我有角色为“SuperUser”、Admin、“Manager”、“Registered” 的用户。
所有在该站点注册的用户都具有“已注册”角色(例如,“经理”用户也具有“已注册”角色)。
现在我必须管理用户 Controller 上的删除 操作。我想要达到的是:
- “已注册”用户只能删除自己(即:从站点注册中删除)
- “经理”用户可以删除自己和“注册”用户,错误不能删除“ super 用户”和“管理员”
- “Admin”用户可以删除自己,“Managers”和“Registered”用户,错误不能删除“SuperUser”
- “ super 用户”用户可以删除所有用户角色,甚至是 super 用户。
所以我从以下代码开始:
[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
是用户管理器存储库和 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/