2010-03-24 11 views
20

Vorrei reindirizzare a loginUrl a meno che non stia utilizzando anche un ruolo, ad esempio [Authorize (Roles="Admin")]. In tal caso, voglio semplicemente visualizzare una pagina che dice che l'utente non è autorizzato.Come reindirizzare [Autorizza] per loginUrl solo quando i ruoli non vengono utilizzati?

Cosa devo fare?

+0

ho chiesto la stessa domanda qui: http://stackoverflow.com/questions/2322366/how-do -i-servire-su-un-non autorizzato-pagina-quando-un-utente-non-nei-ruoli-autorizzati –

+1

Robert: Grazie. Ho cercato post simili prima di postare, ma non ho visto i tuoi. Con quale soluzione sei andato? – royco

+2

Ho finito con il rollare il mio attributo 'AuthorizeRoles', usando il codice da' AuthorizeAttribute' e modificandolo. Se puoi aspettare fino a domani, posterò il codice. –

risposta

24

Ecco il codice dalla mia implementazione modificata di AuthorizeAttribute; L'ho chiamato SecurityAttribute. L'unica cosa che ho cambiato è il metodo OnAuthorization, e ho aggiunto una proprietà stringa aggiuntiva per l'URL per reindirizzare a una pagina non autorizzata:

// 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); 
    } 
} 

Si chiamano allo stesso modo come l'originale AuthorizeAttribute, tranne che non è una proprietà aggiuntiva per ignorare il non autorizzato URL della pagina:

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

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

Grazie, funziona bene. Invece di modificare AuthorizeAttribute.cs, ho semplicemente ereditato da esso. Ora posso usare i ruoli con [Autorizza] e il mio codice sarà enormemente semplificato. Grazie ancora. – royco

+0

Robert: Devo chiamare HandleUnauthorizedRequest (filterContext) da AuthorizeCore, dove filterContext non è disponibile. Potrei semplicemente passare filterContext a AuthorizeCore intead di filterContext.HttpContext. Pensieri? – royco

+0

@Bob: AuthorizeCore è solo un metodo locale, quindi dovresti essere in grado di fare tutto ciò che vuoi con esso. –

3

Il modo più semplice che ho trovato è estendere e personalizzare l'AuthorizeAttribute in modo che faccia qualcosa di diverso (cioè, non impostare un HttpUnauthorizedResult) quando il controllo del ruolo fallisce. Ho scritto uno article sul mio blog che potresti trovare utile. L'articolo descrive molto ciò che si desidera, anche se va oltre e consente all'utente che "possiede" i dati di accedere anche all'azione. Penso che dovrebbe essere abbastanza facile da modificare per i tuoi scopi: devi solo rimuovere la parte "o proprietario".

+0

Le sole risposte del collegamento sono disapprovate perché se il collegamento non funziona più, la risposta diventa inutile, per favore includi il contenuto del link nella risposta qui. –

+1

La risposta fa riferimento al mio post sul blog e descrive l'approccio generale, e quindi non è una risposta "solo link". Non riesco a vedere la necessità di replicare l'intero post qui. – tvanfosson

13

estendere la classe AuthorizeAttribute e sovrascrivere 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 
{ 

} 

E assicurarsi di aggiungere la voce AppSettings nella configurazione

<appSettings> 
    <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" /> 
</appSettings> 
Problemi correlati