15

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

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

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

5 回答 5

7

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

public class SystemAdministratorAuthorizationRequiredAttribute
        : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(System.Security.Principal.IPrincipal user)
        {
            return
                user.IsInRole(
                StringResources.AdministrationViewsStrings.SystemAdministratorRoleName
                );
        }
    }
于 2009-01-16T16:14:48.770 回答
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
于 2008-12-18T04:58:16.027 回答
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 文件中执行此操作,以便只需要执行一次。

于 2008-12-18T02:02:11.843 回答
2

像这样创建一个自定义属性(大卫·海登的博客提供的稍微修改的版本):

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

于 2010-01-23T18:33:44.307 回答
1

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

[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class AuthorizedGmp : AuthorizeAttribute
{
    public AuthorizedGmp()
    {
        Roles = Config.GMPUser;
    }
}
于 2012-05-02T12:58:27.843 回答