2008-12-18 11 views
15

Tengo un problema al configurar el atributo Autorizar el valor de Rol 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.ASP.NET MVC: Problema al establecer el atributo Autorizar Rol de una variable, requiere const

¿Hay alguna manera de verificar el rol 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(); 
    } 

Respuesta

2

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 de atributo, luego usar reflection en el tipo de 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 podría hacer esto en su archivo Global.asax al iniciar la aplicación de modo que sólo hay que hacer una vez.

+0

No se pueden modificar los atributos - el cambio no se "pegue". –

+0

@Marc - nunca lo había intentado y solo estaba agarrando pajas ... – tvanfosson

+0

Gracias User.IsInRole es la solución que voy a implementar. ¿Cómo implementaría esto por cada controlador? Preferiría no tener que implementarlo para cada acción cuando no sea necesario. – tsquillario

4

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. La User.InRole("RoleName") de tvanfosson es probablemente la mejor opción (tiene mi +1).

Sólo 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); 
    } 
} 

Lienzo:

Original: abc 
Updated: def 
Look again: abc 
7

tengo una clase llamada StringResources que proporciona acceso a los 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 
       ); 
     } 
    } 
2

Crear un atributo personalizado como tal (versión ligeramente modificada proporcionada por david hayden's blog):

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

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

y aplicar de este modo:

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

ahora se puede poner toda su lógica de autorización personalizada dentro de tu 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 lo he intentado.

1

Se puede crear una nueva clase Autorizar así:

[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)] 
public class AuthorizedGmp : AuthorizeAttribute 
{ 
    public AuthorizedGmp() 
    { 
     Roles = Config.GMPUser; 
    } 
} 
Cuestiones relacionadas