2010-03-24 8 views
20

Me gustaría [Authorize] para redirigir a loginUrl a menos que también esté usando un rol, como [Authorize (Roles="Admin")]. En ese caso, simplemente quiero mostrar una página que indique que el usuario no está autorizado.¿Cómo redirigir [Autorizar] a loginUrl solo cuando no se utilizan Roles?

¿Qué debo hacer?

+0

me hice la misma pregunta aquí: http://stackoverflow.com/questions/2322366/how-do -i-serve-up-an-unauthorized-page-when-a-user-is-not-in-the-authorised-roles –

+1

Robert: Gracias. Busqué publicaciones similares antes de publicarlas, pero no vi las suyas. ¿Con qué solución fuiste? – royco

+2

Terminé rolando mi propio atributo 'AuthorizeRoles', usando el código de' AuthorizeAttribute' y modificándolo. Si puedes esperar hasta mañana, publicaré el código. –

Respuesta

24

Aquí está el código de mi implementación modificada de AuthorizeAttribute; Lo llamé SecurityAttribute. La única cosa que he cambiado es el método OnAuthorization, y añade una propiedad de cadena adicional para la dirección URL para redirigir a una página no autorizada:

// Set default Unauthorized Page Url here 
private string _notifyUrl = "/Error/Unauthorized"; 

public string NotifyUrl { 
    get { return _notifyUrl; } set { _notifyUrl = value; } 
} 

public override void OnAuthorization(AuthorizationContext filterContext) { 
    if (filterContext == null) { 
     throw new ArgumentNullException("filterContext"); 
    } 

    if (AuthorizeCore(filterContext.HttpContext)) { 
     HttpCachePolicyBase cachePolicy = 
      filterContext.HttpContext.Response.Cache; 
     cachePolicy.SetProxyMaxAge(new TimeSpan(0)); 
     cachePolicy.AddValidationCallback(CacheValidateHandler, null); 
    } 

    /// This code added to support custom Unauthorized pages. 
    else if (filterContext.HttpContext.User.Identity.IsAuthenticated) 
    { 
     if (NotifyUrl != null) 
      filterContext.Result = new RedirectResult(NotifyUrl); 
     else 
      // Redirect to Login page. 
      HandleUnauthorizedRequest(filterContext); 
    } 
    /// End of additional code 
    else 
    { 
     // Redirect to Login page. 
     HandleUnauthorizedRequest(filterContext); 
    } 
} 

usted lo llama de la misma manera que el original AuthorizeAttribute, excepto que hay es una propiedad adicional para reemplazar la URL de la página no autorizada:

// Use custom Unauthorized page: 
[Security (Roles="Admin, User", NotifyUrl="/UnauthorizedPage")] 

// Use default Unauthorized page: 
[Security (Roles="Admin, User")] 
+0

Gracias, esto funciona bien. En lugar de modificar AuthorizeAttribute.cs, simplemente heredé de él. Ahora puedo usar Roles con [Autorizar] y mi código se simplificará enormemente. Gracias de nuevo. – royco

+0

Robert: necesito llamar a HandleUnauthorizedRequest (filterContext) desde AuthorizeCore, donde filterContext no está disponible. Podría pasar filterContext a AuthorizeCore intead de filterContext.HttpContext. ¿Pensamientos? – royco

+0

@Bob: AuthorizeCore es solo un método local, por lo que debería poder hacer lo que quiera con él. –

3

La forma más fácil que he encontrado es extender y personalizar el atributo Autorizar para que haga algo diferente (es decir, no establecer un HttpUnauthorizedResult) cuando falla la comprobación de función. Escribí un article sobre esto en mi blog que podría serle útil. El artículo describe mucho lo que usted desea, aunque va más allá y permite que el usuario que "posee" los datos también tenga acceso a la acción. Creo que debería ser bastante fácil de modificar para tus propósitos; solo necesitarías eliminar la parte "o el propietario".

+0

Las respuestas del enlace solo están mal vistas porque si el enlace ya no funciona, la respuesta se vuelve inútil, por favor incluya aquí el contenido del enlace en la respuesta. –

+1

La respuesta hace referencia a mi propia publicación de blog y describe el enfoque general, por lo que no es una respuesta de "solo enlace". No veo la necesidad de replicar la publicación completa aquí. – tvanfosson

13

extender la clase AuthorizeAttribute y anular HandleUnauthorizedRequest

public class RoleAuthorizeAttribute : AuthorizeAttribute 
{ 
    private string redirectUrl = ""; 
    public RoleAuthorizeAttribute() : base() 
    { 
    } 

    public RoleAuthorizeAttribute(string redirectUrl) : base() 
    { 
     this.redirectUrl = redirectUrl; 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAuthenticated) 
     { 
      string authUrl = this.redirectUrl; //passed from attribute 

      //if null, get it from config 
      if (String.IsNullOrEmpty(authUrl)) 
       authUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["RolesAuthRedirectUrl"]; 

      if (!String.IsNullOrEmpty(authUrl)) 
       filterContext.HttpContext.Response.Redirect(authUrl); 
     } 

     //else do normal process 
     base.HandleUnauthorizedRequest(filterContext); 
    } 
} 

Uso

[RoleAuthorize(Roles = "Admin, Editor")] 
public class AccountController : Controller 
{ 

} 

Y asegúrese de agregar su entrada AppSettings en la configuración

<appSettings> 
    <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" /> 
</appSettings> 
Cuestiones relacionadas