【问题标题】:Dynamically add roles to authorize attribute for controller动态添加角色以授权控制器的属性
【发布时间】:2015-07-17 22:33:54
【问题描述】:

我需要让我的管理员用户即时更改用户的访问权限,以便他们可以创建新角色并向这些角色添加权限。

我希望能够创建一个Authorize 属性以粘贴在我可以从数据库中添加角色的控制器类之上,这样我就不必在开发过程中“设置”角色,如@ 987654323@等

比如[Authorize(Roles = GetListOfRoles()]

我发现了这个问题 - ASP.NET MVC Authorize user with many roles,它做了类似的事情,但也许有办法改变它,以便从数据库中获取权限/角色列表?

【问题讨论】:

  • 我想您应该创建自定义角色提供程序。但是你应该有数据库中的控制器和所有方法的列表。

标签: c# asp.net asp.net-mvc asp.net-identity authorize-attribute


【解决方案1】:

这样的事情怎么样:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyCustomAuthorizationAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        // Do some logic here to pull authorised roles from backing store (AppSettings, MSSQL, MySQL, MongoDB etc)
        ...
        // Check that the user belongs to one or more of these roles 
        bool isUserAuthorized = ....;

        if(isUserAuthorized) 
            return true;

        return base.AuthorizeCore(httpContext);
    }
}

您可以将它与数据库一起使用,或者只是在 web.config 中维护授权角色列表。

【讨论】:

  • 我想我知道你的目标是什么,但是为了其他可以从这个 q/a 中获得知识的人,你可以编辑你的答案以使其更全面(比如包括授权用户的逻辑,可能还包括来自db的IdentityRoles列表作为示例),然后我将其标记为已接受。
  • 如果您使用与上述类似的实现,您可能会考虑使用return isUserAuthorized;,因为您想确保在未授予用户访问权限时返回 false。
【解决方案2】:

这就是我如何提取一个属性,该属性可以根据用户角色的权限为每个方法授权用户。我希望这对其他人有帮助:

/// <summary>
/// Custom authorization attribute for setting per-method accessibility 
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class SetPermissionsAttribute : AuthorizeAttribute
{
    /// <summary>
    /// The name of each action that must be permissible for this method, separated by a comma.
    /// </summary>
    public string Permissions { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        SalesDBContext db = new SalesDBContext();
        UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        ApplicationDbContext dbu = new ApplicationDbContext();

        bool isUserAuthorized = base.AuthorizeCore(httpContext);

        string[] permissions = Permissions.Split(',').ToArray();

        IEnumerable<string> perms = permissions.Intersect(db.Permissions.Select(p => p.ActionName));
        List<IdentityRole> roles = new List<IdentityRole>();

        if (perms.Count() > 0)
        {
            foreach (var item in perms)
            {
                var currentUserId = httpContext.User.Identity.GetUserId();
                var relatedPermisssionRole = dbu.Roles.Find(db.Permissions.Single(p => p.ActionName == item).RoleId).Name;
                if (userManager.IsInRole(currentUserId, relatedPermisssionRole))
                {
                    return true;
                }
            }
        }
        return false;
    }
}

【讨论】:

  • 如何将SetPermissionsAttribute 与action方法一起使用?我需要与SetPermissionsAttribute 一起传递什么?
  • 已经有一段时间了,但如果我没记错的话,它类似于[SetPermissions="Action1, Action2"],但我不确定。
  • 每个人都应该注意,这是不久前的事情,实际的 LINQ 查询可以改进,应该注入数据库上下文和用户管理器,或者应该注入存储库(如果使用存储库模式) .
  • 只是我的 2 美分小费,通常从属性调用数据库不是一个好主意。
  • @Tohid 但是默认的 MVC Authorize 属性如何在不从数据库中读取内容的情况下检查您的角色等??
猜你喜欢
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 2013-12-03
  • 1970-01-01
相关资源
最近更新 更多