ASP.NET MVC: проблема с настройкой атрибута Authorize Role из переменной требует const
У меня возникла проблема с установкой значения роли атрибута Authorize из переменной. В сообщении об ошибке говорится, что для него требуется переменная const. Когда я создаю переменную типа const, она работает нормально, но я пытаюсь загрузить значение из файла Web.Config или что-то еще, что позволит конечному пользователю установить это. Я использую интегрированную проверку подлинности Windows, поскольку это приложение только для интрасети.
Есть ли способ проверить роль пользователей с контроллера? Я буду использовать это в выражении if для аутентификации вместо атрибута.
[Authorize(Roles = Config.GMPUser)]
public ActionResult Index()
{
return View();
}
Ответы
Ответ 1
Вы можете использовать User.InRole( "RoleName" )
внутри контроллера.
EDIT: приведенный ниже код не будет работать, поскольку GetCustomAttributes(), очевидно, возвращает копию каждого атрибута вместо ссылки на фактический атрибут. Оставленный как ответ, чтобы предоставить контекст для других ответов.
Что касается установки его в атрибуте authorize, единственная идея, которую я имею, это установить его в пустую строку в определении атрибута, а затем использовать отражение типа контроллера для получения и изменения свойства CustomAttribute, соответствующего Авторизованному атрибуту (т.е. тот, тип которого является AuthorizeAttribute) для каждого метода, о котором вы заботитесь. Вы должны иметь возможность установить свойство Roles в свой элемент конфигурации таким образом.
var attributes = typeof(MyController).GetMethod("Index")
.GetCustomAttributes(typeof(AuthorizeAttribute),
false)
as AuthorizeAttribute;
attributes[0].Roles = Config.GMPUser;
Я предполагаю, что вы сделаете это в своем файле Global.asax при запуске приложения, чтобы его нужно было только сделать один раз.
Ответ 2
У меня есть класс под названием StringResources, который обеспечивает доступ к статическим строковым значениям. Я столкнулся с той же проблемой и решил проблему следующим образом. Я унаследовал от класса AuthorizeAttribute и добавил переопределение метода для метода AuthorizeCore. Функциональность метода имела вызов IsInRole() и прошла в статическом свойстве string. Это сделал трюк. Единственная проблема заключается в создании отдельных классов для каждой роли (или для комбинаций ролей любым способом, который диктует ваша бизнес-логика).
public class SystemAdministratorAuthorizationRequiredAttribute
: AuthorizeAttribute
{
protected override bool AuthorizeCore(System.Security.Principal.IPrincipal user)
{
return
user.IsInRole(
StringResources.AdministrationViewsStrings.SystemAdministratorRoleName
);
}
}
Ответ 3
Атрибуты сжигаются во время компиляции, поэтому, как указано, вы можете использовать их только с константами. Вы также не можете изменять атрибуты, так как даже если вам кажется, что это не "прилипает" в следующий раз, когда вы выберете значение обратно. tvanfosson User.InRole( "RoleName" )
, вероятно, лучший вариант (у него есть мой +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
Ответ 4
Создайте собственный пользовательский атрибут (слегка измененная версия, предоставленная блог david hayden):
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 с предоставленным Accessor. Не уверен, что вы сможете перейти в новый MyAuthorizationService() к нему.
Не пробовал.
Ответ 5
Вы можете создать новый класс авторизации следующим образом:
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class AuthorizedGmp : AuthorizeAttribute
{
public AuthorizedGmp()
{
Roles = Config.GMPUser;
}
}