我在设置变量的Authorize属性Role值时遇到问题。错误消息表明它需要一个const变量。当我创建一个const类型变量时,它工作正常,但我试图从Web.Config文件或其他任何允许最终用户设置此值的文件中加载该值。我正在使用集成Windows身份验证,因为这是一个仅限Intranet的应用程序。
有没有办法从控制器检查用户角色?我将在if语句中使用它来进行身份验证而不是属性。
[Authorize(Roles = Config.GMPUser)]
public ActionResult Index()
{
return View();
}
答案 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;
}
}