Настраиваемый фильтр авторизации MVC

Я хочу сделать атрибут [MyAuthorize(Role="R1")], чтобы "R1" можно было сделать настраиваемым вместо жесткого кодирования на Controller / Action.

Обычный подход к созданию [MyAuthorize(Role="R1")] кажется

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    private readonly string[] _allowedRoles;

    public MyAuthorizeAttribute(params string[] roles)
    {
        this._allowedRoles = roles;
    }
    protected override bool OnAuthorization(AuthorizationContext 
                                             authorizationContext)

    {
        bool authorize = false;

        // Compare current user's Roles with "R1" to figure out if the 
        // Action / Controller can be executed   

        return authorize;
    }
}

Но что, если такие роли, как "R1", могут быть изменены в любое время? то есть быть "R1" в один день и называться "AssistantManager" в другой день.

Приложение должно быть перекодировано, чтобы справиться с этим.

Я подумал о создании пользовательского атрибута [OnAuthorize], который читается (Действие/Контроллер, Роль) как key value pairs из файла web.config.

Eg:--

  <add key="Controller1" value="Role1" />
  <add key="Action2" value="Role2" />

а в атрибуте..

protected override bool OnAuthorization(AuthorizationContext 
                                         authorizationContext)

{
    bool authorize = false;

    // 1. Read all key values 
    // 2. determine Action / Controller the user is trying to go
    // 3. Compare user's roles with those for Action / Controller

    return authorize;
}

Я знаю об ограничениях <location .... /> в MVC согласно https://stackoverflow.com/a/11765196/807246 и не утверждаю этого, хотя читаю из web.config

Но что, если мы прочитаем (..и сохраним в сеансе??) всю конфигурацию, связанную с авторизацией, при первой загрузке приложения?

Любые изменения типа "R1" -> "AssistantManager" ;; "R2" -> "Manager" должен просто требовать перезапуска приложения, вместо того, чтобы вносить изменения в код в контроллере/действии.


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


person heyNow    schedule 23.04.2019    source источник


Ответы (1)


Объявление 1. Вы читаете настройку с помощью API конфигурации, например. если это обычный MVC, вам нужно ConfigurationManager.AppSettings заглянуть в раздел настроек приложения web.config

Объявление 2. Вы ничего не определяете или, скорее, вы, кажется, неправильно поняли связанный пост. Что вы делаете, так это кладете Authorize на контроллер (действие), которое хотите защитить, и OnAuthorization запускается, когда контроллер/действие выполняется. Если очень хочется, можно заглянуть в контекст авторизации, переданный в качестве аргумента, контроллер и действие доступны в данных маршрута.

Объявление 3. Это самая простая часть: текущий зарегистрированный пользователь (или анонимный пользователь, если пользователь еще не аутентифицирован) передается в свойстве authorizationContext.HttpContext.User как IPrincipal, поэтому вы даже можете вызвать его метод IsInRole.

Но что, если мы прочитаем (..и сохраним в сеансе??) всю конфигурацию, связанную с авторизацией, при первой загрузке приложения.

Вы действительно не должны. Даже если читать из конфигурации при каждом запросе, конфигурация уже предзагружается при каждом перезапуске приложения, особо ничего не тормозишь тогда с ConfigurationManager.AppSettings.

Любые изменения типа "R1" -> "AssistantManager" ;; «R2» -> «Менеджер» должен просто требовать перезапуска приложения, вместо того, чтобы вносить изменения в код в контроллере/действии.

Если вы сохраните его в файле конфигурации и его изменение приведет к перезапуску пула приложений, вы не внесете никаких изменений в код.

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

Существуют риски: кто-то, кто может получить доступ к вашему серверу приложений, может перенастроить ваше приложение. Однако обратите внимание, что такой кто-то может причинить и любой другой вред, например. декомпилируйте, измените, перекомпилируйте и повторно загрузите ваше приложение. Или даже заменить его чем-то совершенно другим.

Что касается альтернатив, то совершенно невозможно придумать что-то лучше, если критерии того, что лучше, расплывчаты. Если что-то, возможно, лучше, нам нужно знать, что означает лучше.

Другими словами, это выглядит нормально.

person Wiktor Zychla    schedule 23.04.2019
comment
Спасибо за ваше понимание. Лучше, здесь просто означает более безопасный, без рисков, упомянутых в https://stackoverflow.com/a/11765196/807246 - person heyNow; 23.04.2019
comment
Как я уже сказал, декларативная авторизация web.config не применяется к контроллерам/действиям MVC, о чем также упоминается в связанном сообщении. Придерживайтесь авторизации на основе атрибутов/фильтров, если вы не уверены. - person Wiktor Zychla; 23.04.2019