Динамически добавлять роли для авторизации атрибута для контроллера

Мне нужно, чтобы мой администратор мог изменять права доступа для пользователей "на лету", чтобы они могли создавать новые роли и добавлять разрешения для этих ролей.

Я хочу, чтобы создать атрибут Authorize, чтобы придерживаться выше моего класса контроллера, что я могу добавить роли из базы данных, так что мне не нужно "устанавливать" роли во время разработки, как в [Authorize(Roles="Role1, Role2")] и т.д.

Итак, что-то вроде [Authorize(Roles = GetListOfRoles()]

Я нашел этот вопрос - ASP.NET MVC Авторизовать пользователя со многими ролями, который делает что-то похожее, но может быть, есть способ изменить это, чтобы получить список разрешения/роли из db?

Ответы

Ответ 1

Вот как я снял атрибут, который может разрешать пользователям на один метод на основе разрешений роли этого пользователя. Надеюсь, это поможет кому-то еще:

/// <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;
    }
}

Ответ 2

Что-то вроде этого:

[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.