ASP.NET MVC: проблема с установкой атрибута Authorle Role из переменной, требует const - PullRequest
15 голосов
/ 18 декабря 2008

У меня проблема с установкой значения роли атрибута Authorize из переменной. Сообщение об ошибке говорит, что требуется переменная const. Когда я создаю переменную типа const, она работает нормально, но я пытаюсь загрузить значение из файла Web.Config или чего-либо еще, что позволит конечному пользователю установить это. Я использую встроенную проверку подлинности Windows, поскольку это приложение только для интрасети.

Есть ли способ проверить роль пользователей с контроллера? Я буду использовать это в операторе if для аутентификации вместо атрибута.

[Authorize(Roles = Config.GMPUser)]
public ActionResult Index()
   {
      return View();
   }

Ответы [ 5 ]

7 голосов
/ 16 января 2009

У меня есть класс StringResources, который обеспечивает доступ к статическим строковым значениям. Я столкнулся с тем же препятствием и решил проблему следующим образом. Я унаследовал от класса AuthorizeAttribute и добавил переопределение метода для метода AuthorizeCore. Функциональные возможности метода имели вызов IsInRole () и передаются в свойство статической строки. Это добилось цели. Единственная проблема состоит в том, чтобы создавать отдельные классы для каждой роли (или для комбинаций ролей в зависимости от того, что диктует ваша бизнес-логика).

public class SystemAdministratorAuthorizationRequiredAttribute
        : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(System.Security.Principal.IPrincipal user)
        {
            return
                user.IsInRole(
                StringResources.AdministrationViewsStrings.SystemAdministratorRoleName
                );
        }
    }
4 голосов
/ 18 декабря 2008

Атрибуты записываются во время компиляции, поэтому, как указано, вы можете использовать их только с константами. Вы также не можете изменить атрибуты, так как даже если вам кажется, что это не «прилипает» в следующий раз, когда вы извлекаете значение обратно. User.InRole( "RoleName" ) у tvanfosson, вероятно, лучший вариант (у него мой +1).

Просто для иллюстрации проблемы с обновлением атрибутов:

class FooAttribute : Attribute
{
    public string Bar { get; set; }
}
static class Program
{
    [Foo(Bar="abc")]
    public static void Main()
    {
        MethodInfo method = typeof(Program).GetMethod("Main");
        var attrib = (FooAttribute) Attribute.GetCustomAttribute(method, typeof(FooAttribute));
        Console.WriteLine("Original: " + attrib.Bar);
        attrib.Bar = "def";
        Console.WriteLine("Updated: " + attrib.Bar);
        attrib = (FooAttribute)Attribute.GetCustomAttribute(method, typeof(FooAttribute));
        Console.WriteLine("Look again: " + attrib.Bar);
    }
}

Печать:

Original: abc
Updated: def
Look again: abc
2 голосов
/ 23 января 2010

Создайте пользовательский атрибут следующим образом (слегка измененная версия, предоставленная блогом Дэвида Хейдена ):

public class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
    public IAuthorizationService _authorizationService = new MyAuthorizationService();

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
       return _authorizationService.Authorize(httpContext);
    }
}

и применять так:

[MyCustomAuthorize]
public ActionResult Create()
{
    return View();
}

теперь вы можете поместить всю свою собственную логику авторизации в свой собственный класс MyAuthorizationService. Примечание: в решении davids вы можете установить внутреннюю службу MyAuthorizationService с помощью предоставленного средства доступа. Не уверен, сможете ли вы передать ему новый MyAuthorizationService (). Я не пробовал это.

2 голосов
/ 18 декабря 2008

Вы можете использовать User.InRole( "RoleName" ) в контроллере.

РЕДАКТИРОВАТЬ: приведенный ниже код не будет работать, поскольку GetCustomAttributes (), очевидно, возвращает копию каждого атрибута вместо ссылки на фактический атрибут. Оставлено как ответ, чтобы обеспечить контекст для других ответов.

Что касается установки его в атрибуте authorize, единственная идея, которая у меня есть, - установить для нее пустую строку в определении атрибута, а затем использовать отражение в типе контроллера, чтобы получить и изменить свойство CustomAttribute, соответствующее AuthorizeAttribute. (т. е. тот, тип которого AuthorizeAttribute) для каждого метода, который вас интересует. Таким образом вы сможете установить свойство Roles для вашего элемента конфигурации.

var attributes = typeof(MyController).GetMethod("Index")
                                     .GetCustomAttributes(typeof(AuthorizeAttribute),
                                                          false)
                 as AuthorizeAttribute;

attributes[0].Roles = Config.GMPUser;

Я полагаю, что вы должны сделать это в файле Global.asax при запуске приложения, так что это нужно сделать только один раз.

1 голос
/ 02 мая 2012

Вы можете создать новый класс Authorize следующим образом:

[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class AuthorizedGmp : AuthorizeAttribute
{
    public AuthorizedGmp()
    {
        Roles = Config.GMPUser;
    }
}
...