ASP.NET MVC: Problem setting the Authorize attribute Role from a variable, requires const

為{幸葍}努か 提交于 2019-12-03 01:58:09

You can use User.InRole( "RoleName" ) within a controller.

EDIT: The code below will not work since GetCustomAttributes() apparently returns a copy of each attribute instead of a reference to the actual attribute. Left as answer to provide context for other answers.

As far as setting it in the authorize attribute, the only idea that I have is to set it to the empty string in the attribute definition, then use reflection on the controller's type to get and modify the CustomAttribute property corresponding to the AuthorizeAttribute (i.e., the one whose type is AuthorizeAttribute) for each method you care about. You should be able to set the Roles property to your configuration item that way.

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

attributes[0].Roles = Config.GMPUser;

I suppose that you would do this in your Global.asax file on application start so that it only needs to be done once.

I have a class called StringResources that provides access to static string values. I ran into the same snag and solved the problem in the following manner. I inherited from the AuthorizeAttribute class and added a method override for the AuthorizeCore method. The functionality of the method had a call to IsInRole() and passes in the static string property. That did the trick. The only problem is having to create separate classes for each role (or for combinations of roles in whatever manner your business logic dictates).

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

Attributes are burned at compile time, so as indicated, you can only use them with constants. You also can't change attributes, since even if it seems to let you, it doesn't "stick" next time you fetch the value back out. tvanfosson's User.InRole( "RoleName" ) is probably the best option (he has my +1).

Just to illustrate the issue with updating attributes:

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);
    }
}

Prints:

Original: abc
Updated: def
Look again: abc
Areg Sarkissian

Create a custom attribute like so (slightly modified version provided by david hayden's blog):

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

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

and apply like so:

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

now you can put all your custom authorization logic inside your own MyAuthorizationService class. Note: in davids solution you can set the internal MyAuthorizationService with the provided accessor. Not sure if you will be able pass in a new MyAuthorizationService() to it. Haven't tried that.

You could create a new Authorize class like so:

[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class AuthorizedGmp : AuthorizeAttribute
{
    public AuthorizedGmp()
    {
        Roles = Config.GMPUser;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!