C# ASP.NET MVC:从变量设置授权属性角色时出现问题,需要常量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/376655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET MVC: Problem setting the Authorize attribute Role from a variable, requires const
提问by tsquillario
I am having a problem setting the Authorize attribute Role value from a variable. The error message says it requires a const variable. When I create a const type variable it works fine but I am trying to load the value from the Web.Config file or anything else that will allow the end user to set this. I'm using integrated Windows authentication since this is an intranet only application.
我在从变量设置授权属性角色值时遇到问题。错误消息说它需要一个 const 变量。当我创建一个 const 类型变量时,它工作正常,但我试图从 Web.Config 文件或其他任何允许最终用户设置它的文件加载值。我正在使用集成的 Windows 身份验证,因为这是一个仅限 Intranet 的应用程序。
Is there a way to check the users role from a controller? I will use this in an if statement to authenticate instead of an attribute.
有没有办法从控制器检查用户角色?我将在 if 语句中使用它来进行身份验证而不是属性。
[Authorize(Roles = Config.GMPUser)]
public ActionResult Index()
{
return View();
}
采纳答案by tvanfosson
You can use User.InRole( "RoleName" )
within a controller.
您可以User.InRole( "RoleName" )
在控制器内使用。
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.
编辑:下面的代码将不起作用,因为 GetCustomAttributes() 显然返回每个属性的副本,而不是对实际属性的引用。留作答案以提供其他答案的上下文。
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.
至于在authorize属性中设置,我唯一的想法是在属性定义中将其设置为空字符串,然后使用控制器类型的反射来获取和修改AuthorizeAttribute对应的CustomAttribute属性(即,类型为 AuthorizeAttribute 的那个),用于您关心的每个方法。您应该能够以这种方式将 Roles 属性设置为您的配置项。
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.
我想您会在应用程序启动时在 Global.asax 文件中执行此操作,以便只需要执行一次。
回答by Marc Gravell
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).
属性在编译时被烧毁,因此如所示,您只能将它们与常量一起使用。您也无法更改属性,因为即使它似乎允许您,下次您取回值时它也不会“粘住”。tvanfosson'sUser.InRole( "RoleName" )
可能是最好的选择(他有我的 +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
回答by brady gaster
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).
我有一个名为 StringResources 的类,它提供对静态字符串值的访问。我遇到了同样的问题,并通过以下方式解决了这个问题。我从 AuthorizeAttribute 类继承并为 AuthorizeCore 方法添加了一个方法覆盖。该方法的功能调用 IsInRole() 并传入静态字符串属性。这就是诀窍。唯一的问题是必须为每个角色(或以您的业务逻辑规定的任何方式为角色组合)创建单独的类。
public class SystemAdministratorAuthorizationRequiredAttribute
: AuthorizeAttribute
{
protected override bool AuthorizeCore(System.Security.Principal.IPrincipal user)
{
return
user.IsInRole(
StringResources.AdministrationViewsStrings.SystemAdministratorRoleName
);
}
}
回答by Areg Sarkissian
Create a custom attribute like so (slightly modified version provided by david hayden's blog):
像这样创建一个自定义属性(david hayden 的博客提供的稍微修改的版本):
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.
现在您可以将所有自定义授权逻辑放在您自己的 MyAuthorizationService 类中。注意:在 davids 解决方案中,您可以使用提供的访问器设置内部 MyAuthorizationService。不确定您是否可以将新的 MyAuthorizationService() 传递给它。没试过。
回答by duedl0r
You could create a new Authorize class like so:
您可以像这样创建一个新的 Authorize 类:
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class AuthorizedGmp : AuthorizeAttribute
{
public AuthorizedGmp()
{
Roles = Config.GMPUser;
}
}