ASP.NET MVC:从变量设置Authorize属性Role的问题,需要const

我在从变量设置Authorize属性Role值时遇到问题。 错误消息表明它需要一个const变量。 当我创建一个const类型变量时它工作正常,但我试图从Web.Config文件或其他任何允许最终用户设置此值的文件中加载该值。 我正在使用集成的Windows身份validation,因为这是一个仅限Intranet的应用程序。

有没有办法从控制器检查用户角色? 我将在if语句中使用它来进行身份validation而不是属性。

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

您可以在控制器中使用User.InRole( "RoleName" )

编辑:以下代码将无法工作,因为GetCustomAttributes()显然返回每个属性的副本而不是对实际属性的引用。 留下作为答案,为其他答案提供背景。

至于在authorize属性中设置它,我唯一的想法是将它设置为属性定义中的空字符串,然后在控制器的类型上使用reflection来获取和修改与AuthorizeAttribute相对应的CustomAttribute属性(即,对于您关心的每种方法,其类型为AuthorizeAttribute的那个。 您应该可以将Roles属性设置为您的配置项。

 var attributes = typeof(MyController).GetMethod("Index") .GetCustomAttributes(typeof(AuthorizeAttribute), false) as AuthorizeAttribute; attributes[0].Roles = Config.GMPUser; 

我想你会在应用程序启动时在你的Global.asax文件中执行此操作,这样它只需要完成一次。

我有一个名为StringResources的类,它提供对静态字符串值的访问。 我碰到了同样的问题并以下列方式解决了问题。 我从AuthorizeAttribute类inheritance并为AuthorizeCore方法添加了方法覆盖。 该方法的function调用了IsInRole()并传入静态字符串属性。 这就是诀窍。 唯一的问题是必须为每个角色创建单独的类(或者以业务逻辑规定的任何方式为角色组合创建)。

 public class SystemAdministratorAuthorizationRequiredAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(System.Security.Principal.IPrincipal user) { return user.IsInRole( StringResources.AdministrationViewsStrings.SystemAdministratorRoleName ); } } 

属性在编译时刻录,如图所示,您只能将它们与常量一起使用。 你也无法改变属性,因为即使它似乎让你,它也不会在你下次取回值时“坚持”。 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 

像这样创建一个自定义属性(由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。 不确定您是否可以将新的MyAuthorizationService()传递给它。 没试过。

您可以像这样创建一个新的Authorize类:

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