ASP.NET MVC Как AuthorizeAttribute поддерживает проверку ролей?

В моих контроллерах у меня есть код типа [Authorize(Roles = "Administrators")], аннотированный над некоторыми действиями, и я хочу знать, как AuthorizeAttribute использует параметр Roles (реализация механизма проверки). Моя цель — создать расширение этого класса, например PrivilegeAttribute, чтобы я мог аннотировать такие действия, как [Privilege(Privileges = "read")]. В этом классе я бы проверил, имеет ли роль пользователя хотя бы одну из привилегий в этом пользовательском фильтре (в этом примере read). Я уже создал связь между ролями и привилегиями в коде и в базе данных, и мне нужна помощь, чтобы проверить, связана ли роль с привилегией.

Я пытался посмотреть, есть ли эта информация в HttpContextBase.User.Identity, но не смог ее найти. Спасибо.


person ITWorker    schedule 12.08.2016    source источник
comment
Проверьте этот вопрос: stackoverflow.com/questions/5117782/. Я также нашел это руководство: diaryofaninja.com/blog/2011/07/24/   -  person Eitan K    schedule 12.08.2016


Ответы (1)


Если вам не нужен собственный настраиваемый атрибут и вы можете использовать чужой атрибут, я бы предложил использовать пакет Thinktecture.IdentityModel.Owin.ResourceAuthorization.Mvc, как описано здесь.

Сообщение в блоге Доминика Байер

и тут

Пример кода Git Hub для пакета

так что в основном это работает так: вы помещаете атрибут над своим действием следующим образом:

[ResourceAuthorize("View", "Customer")]

Первый аргумент — это имя проверяемого действия, второй — имя атрибута.

Затем вы наследуете ResourceAuthorizationManager в своем коде и переопределяете метод CheckAccessAssync.

public class MyAuthorization : ResourceAuthorizationManager
{
    public override Task<bool> CheckAccessAsync(ResourceAuthorizationContext context)
    {
        var resource = context.Resource.First().Value;
        var action =  context.Action.First().Value;

        // getting the roles that are connected to that resource and action
        // from the db. Context could of course be injected into the 
        // constructor of the class. In my code I assume that the table
        // thank links roles, resources and actions is called Roles ToActions
        using(var db = MyContext())
        var roles = db.RolesToActions   // Use your table name here
         .Where(r => r.Resource == resource && r.Action == action).ToList();

        foreach(var role in roles)
        {
            if(context.Principal.IsInRole(role.Name)
            {
                return Ok();
            }
        }

        return Nok();
    }
 }

}

Так что я надеюсь, что это поможет. Однако, если вы предпочитаете реализовать свой собственный атрибут, а не исходный код из Репозиторий ResourceAuthorization GitHub должен стать хорошей отправной точкой.

person Andre Kraemer    schedule 13.08.2016