c# - example - ASP.NET MVC: el problema al configurar el atributo Autorizar rol de una variable, requiere const
mvc roles authorization (5)
Los atributos se graban en tiempo de compilación, por lo que, como se indica, solo puede usarlos con constantes. Tampoco puede cambiar los atributos, ya que incluso si parece permitirse, no se "pegará" la próxima vez que recupere el valor. El User.InRole( "RoleName" )
es probablemente la mejor opción (tiene mi +1).
Solo para ilustrar el problema con la actualización de atributos:
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);
}
}
Huellas dactilares:
Original: abc
Updated: def
Look again: abc
Tengo un problema al configurar el valor Autorizar el atributo de una variable. El mensaje de error dice que requiere una variable const. Cuando creo una variable de tipo const funciona bien, pero estoy tratando de cargar el valor del archivo Web.Config o cualquier otra cosa que permita al usuario final configurarlo. Estoy usando la autenticación de Windows integrada, ya que esta es una aplicación de intranet solamente.
¿Hay alguna manera de verificar la función de los usuarios desde un controlador? Usaré esto en una instrucción if para autenticar en lugar de un atributo.
[Authorize(Roles = Config.GMPUser)]
public ActionResult Index()
{
return View();
}
Puede usar User.InRole( "RoleName" )
dentro de un controlador.
EDITAR: El código siguiente no funcionará, ya que GetCustomAttributes () aparentemente devuelve una copia de cada atributo en lugar de una referencia al atributo real. Se dejó como respuesta para proporcionar contexto para otras respuestas.
En cuanto a establecerlo en el atributo authorize, la única idea que tengo es establecerlo en la cadena vacía en la definición del atributo, luego usar la reflexión en el tipo del controlador para obtener y modificar la propiedad CustomAttribute correspondiente a AuthorizeAttribute (es decir, aquel cuyo tipo es AuthorizeAttribute) para cada método que le interese. Debería poder establecer la propiedad Funciones en su elemento de configuración de esa manera.
var attributes = typeof(MyController).GetMethod("Index")
.GetCustomAttributes(typeof(AuthorizeAttribute),
false)
as AuthorizeAttribute;
attributes[0].Roles = Config.GMPUser;
Supongo que harías esto en tu archivo Global.asax al inicio de la aplicación para que solo tenga que hacerse una vez.
Tengo una clase llamada StringResources que proporciona acceso a valores de cadena estáticos. Me encontré con el mismo inconveniente y resolví el problema de la siguiente manera. Heredé de la clase AuthorizeAttribute y agregué un método anulado para el método AuthorizeCore. La funcionalidad del método tenía una llamada a IsInRole () y pasa en la propiedad de cadena estática. Eso hizo el truco. El único problema es tener que crear clases separadas para cada rol (o para combinaciones de roles de cualquier forma que dicte su lógica de negocios).
public class SystemAdministratorAuthorizationRequiredAttribute
: AuthorizeAttribute
{
protected override bool AuthorizeCore(System.Security.Principal.IPrincipal user)
{
return
user.IsInRole(
StringResources.AdministrationViewsStrings.SystemAdministratorRoleName
);
}
}
Podrías crear una nueva clase Authorize como esta:
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class AuthorizedGmp : AuthorizeAttribute
{
public AuthorizedGmp()
{
Roles = Config.GMPUser;
}
}
Cree un atributo personalizado como ese (versión ligeramente modificada proporcionada por el blog de David Hayden ):
public class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
public IAuthorizationService _authorizationService = new MyAuthorizationService();
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return _authorizationService.Authorize(httpContext);
}
}
y aplicar así:
[MyCustomAuthorize]
public ActionResult Create()
{
return View();
}
ahora puede poner toda su lógica de autorización personalizada dentro de su propia clase MyAuthorizationService. Nota: en la solución de davids, puede configurar el MyAuthorizationService interno con el acceso proporcionado. No estoy seguro si podrá pasarle un nuevo MyAuthorizationService (). No he intentado eso.