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

时间:2008-12-18 01:52:54

标签: c# asp.net-mvc authorization

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

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

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

5 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

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

编辑:由于GetCustomAttributes()显然返回每个属性的副本而不是对实际属性的引用,因此下面的代码将无效。留下答案,为其他答案提供背景信息。

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

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

attributes[0].Roles = Config.GMPUser;

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

答案 3 :(得分:2)

创建一个自定义属性(由david hayden's blog提供稍微修改的版本):

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()传递给它。 没试过。

答案 4 :(得分:1)

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

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