2014-10-20 17 views
81

Sto leggendo da diverse risorse (libri e risposte SO) sull'autorizzazione in WebApi.Autorizzazione personalizzata in Asp.net WebApi - che casino?

Supponiamo che io voglio aggiungere attributi personalizzati che consente l'accesso solo per determinati utenti:

Caso # 1

Ho visto questo approccio di sovrascrivendoOnAuthorization, che definisce la risposta se qualcosa è sbagliato

public class AllowOnlyCertainUsers : AuthorizeAttribute 
{ 
public override void OnAuthorization(HttpActionContext actionContext) 
    { 
    if (/*check if user OK or not*/) 
    { 
    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); 
    } 
    } 
} 

caso # 2

Ma ho anche visto questo esempio simile che anche l'override OnAuthorization ma con chiamava base:

public override void OnAuthorization(HttpActionContext actionContext) 
{ 
    base.OnAuthorization(actionContext); 

    // If not authorized at all, don't bother 

    if (actionContext.Response == null) 
    { 
     //... 
    } 
} 

Poi, si controlla se il HttpActionContext.Response è impostato o meno. Se non è impostata, vuol dire che la richiesta è autorizzata e l'utente è ok

Caso # 3

Ma ho visto anche questo approccio di rilevante IsAuthorized:

public class AllowOnlyCertainUsers : AuthorizeAttribute 
{ 
protected override bool IsAuthorized(HttpActionContext context) 
    { 
    if (/*check if user OK or not*/) 
    { 
    return true;// or false 
    } 
    } 
} 

Case # 4

E poi ho visto un esempio simile ma con la chiamata di base. Isautorizzato (contesto):

protected override bool IsAuthorized(HttpActionContext context) 
{ 
if (something1 && something2 && base.IsAuthorized(context)) //?? 
return true; 
return false; 
} 

Una cosa più

E infine Dominick detto here:

Non si dovrebbe ignorare OnAuthorization - perché si sarebbe perdere [AllowAnonymous] manipolazione.

Domande

  • 1) Quali metodi devo usare: IsAuthorized o OnAuthorization? (o quando usare quale)

  • 2) quando devo chiamare base.IsAuthorized or base.OnAutorizzazione?

  • 3) È così che l'hanno costruito? che se la risposta è nulla allora tutto è ok?(Caso # 2)

NB

Si prega di notare, sto usando (e si desidera utilizzare) solo AuthorizeAttribute che eredita già da AuthorizationFilterAttribute

Perché?

Becuase io sono nella prima fase in: http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

enter image description here

Comunque Im chiedendo tramite l'estensione attributo Autorizza.

+0

Che cosa è necessario per sostituire l'attributo Authorize? Qual è l'usecase che vuoi raggiungere? Se è necessario consentire l'accesso a determinati utenti perché non utilizzare l'attributo [Autorizza (Utenti = "Amministratore")] in questo modo? –

+1

@TaiseerJoudeh Ad esempio, provare ad autenticare gli utenti tra le 10:00 e le 12:00 (configurabili). non puoi farlo con ruoli normali e attr. devi fare la tua logica –

risposta

78

Quali metodi dovrei usare: IsAuthorized o OnAuthorization? (O quando usare quale)

si estenderà AuthorizationFilterAttribute se la logica di autorizzazione non dipende l'identità stabilita e ruoli. Per l'autorizzazione relativa all'utente, estendere e utilizzare AuthorizeAttribute. Nel primo caso, sostituirai OnAuthorization. Per quest'ultimo caso, si sostituirà IsAuthorized. Come si può vedere dal codice sorgente di questi attributi, OnAuthorization viene contrassegnato come virtuale per l'override se si deriva da AuthorizationFilterAttribute. D'altra parte, il metodo IsAuthorized è contrassegnato come virtuale in AuthorizeAttribute. Credo che questo sia un buon indicatore dell'uso previsto.

quando dovrei chiamare base.IsAuthorized o base.OnAutorizzazione?

La risposta a questa domanda sta nel modo in cui OO generalmente funziona. Se si esegue l'override di un metodo, è possibile fornire completamente una nuova implementazione o un ruolo secondario sull'implementazione fornita dal genitore e migliorare il comportamento. Ad esempio, prendi il caso di IsAuthorized(HttpActionContext). Il comportamento della classe base consiste nel controllare l'utente/ruolo rispetto a ciò che è specificato nel filtro rispetto all'identità stabilita. Di ', vuoi fare tutto questo ma in aggiunta, vuoi controllare qualcos'altro, può essere basato su un'intestazione di richiesta o qualcosa del genere. In tal caso, puoi fornire un override come questo.

protected override bool IsAuthorized(HttpActionContext actionContext) 
{ 
    bool isAuthroized = base.IsAuthorized(actionContext); 
    // Here you look at the header and do your additional stuff based on actionContext 
    // and store the result in isRequestHeaderOk 
    // Then, you can combine the results 
    // return isAuthorized && isRequestHeaderOk; 
} 

Mi dispiace ma non capisco la tua Q3. A proposito, il filtro di autorizzazione esiste da molto tempo e le persone lo usano per ogni genere di cose e talvolta anche in modo errato.

Un'altra cosa. E finalmente c'era questo ragazzo qui che ha detto: non dovrebbe ignorare OnAuthorization - perché mancherebbe la gestione di [AllowAnonymous].

Il tizio che ha detto che è il Dio del controllo degli accessi - Dominick. Ovviamente sarà corretto. Se si guarda alla realizzazione di OnAuthorization (copiato sotto),

public override void OnAuthorization(HttpActionContext actionContext) 
{ 
    if (actionContext == null) 
    { 
     throw Error.ArgumentNull("actionContext"); 
    } 

    if (SkipAuthorization(actionContext)) 
    { 
     return; 
    } 

    if (!IsAuthorized(actionContext)) 
    { 
     HandleUnauthorizedRequest(actionContext); 
    } 
} 

la chiamata alla SkipAuthorization è la parte che assicura AllowAnonymous filtri vengono applicati, cioè, l'autorizzazione viene saltato. Se si sostituisce questo metodo, si perde questo comportamento. In realtà, se decidi di basare la tua autorizzazione su utenti/ruoli, a quel punto avresti deciso di derivare da AuthorizeAttribute. Solo l'opzione corretta lasciata per te a quel punto sarà quella di ignorare lo IsAuthorized e non il già modificato OnAuthorization, sebbene sia tecnicamente possibile farlo entrambi.

PS. Nell'API Web ASP.NET, esiste un altro filtro chiamato filtro di autenticazione. L'idea è che lo usi per l'autenticazione e il filtro di autorizzazione per l'autorizzazione, come indica il nome. Tuttavia, ci sono molti esempi in cui questo limite è confuso. Un sacco di esempi di filtri di authroization farà un qualche tipo di autenticazione. Ad ogni modo, se hai tempo e vuoi capire un po 'di più, dai un'occhiata a questo MSDN article. Disclaimer: è stato scritto da me.

+0

Grazie ancora, ma se leggo tra le righe IsAuthenticated sono chiamate da OnAuthirization, quindi perché non sovrascrivere OnAuthorization e chiamare base.OnAutorizzazione e quindi controllare la risposta? –

+0

Sicuro, se è quello che vuoi. – Badri

+0

Nella mia terza domanda intendevo: dopo aver eseguito la funzione base - base.OnAutorizzazione ad esempio, l'unico modo per verificare se ha avuto successo- è controllare la proprietà Response ?, ps gli esempi provengono dal tuo libro :-) –

14

Ok, il mio suggerimento è quello di fare le seguenti assumendo che tu stia utilizzando token bearer OAuth per proteggere la tua API Web e stai impostando il permessoTempo come un reclamo per l'utente quando hai emesso il token. Si può leggere di più su token based authentication here

  1. Creare CustomAuthorizeAttribute che deriva dalla AuthorizationFilterAttribute
  2. metodo di sostituzione OnAuthorizationAsync e utilizzare il codice di esempio qui sotto:

    public class CustomAuthorizeAttribute : AuthorizationFilterAttribute 
    { 
    
        public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) 
        { 
    
         var principal = actionContext.RequestContext.Principal as ClaimsPrincipal; 
    
         if (!principal.Identity.IsAuthenticated) 
         { 
          return Task.FromResult<object>(null); 
         } 
    
         var userName = principal.FindFirst(ClaimTypes.Name).Value; 
         var userAllowedTime = principal.FindFirst("userAllowedTime").Value; 
    
         if (currentTime != userAllowedTime) 
         { 
          actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Not allowed to access...bla bla"); 
          return Task.FromResult<object>(null); 
         } 
    
         //User is Authorized, complete execution 
         return Task.FromResult<object>(null); 
    
        } 
    } 
    
  3. Ora nel vostro controller si utilizza CustomAuthorize attributo per proteggere la vostra controllori che utilizzano questa logica di autorizzazione.
+1

Grazie. Ma attualmente sto usando 'AuthorizeAttribute' che eredita' AuthorizationFilterAttribute' e -anche per l'apprendimento ho chiesto espressamente su quale metodo dovrei usare e la risposta ha contenuto o non thingy ... –

2

ASP.NET v5 Introduced a completely new Authorization System. Per coloro che intendono utilizzare .NET 5 suggerisco di passare a Microsoft.AspNet.Authorization.

Praticamente si risolve il problema causato dal mantenimento di entrambi System.Web.Http.Authorize e System.Web.Mvc.Authorize e altre implementazioni di autenticazione meno recenti.

Fornisce un'ottima astrazione dei tipi di azione (Crea, Leggi, Aggiorna, Elimina), Risorse, Ruoli, Reclami, Visualizzazioni, Requisiti personalizzati e consente di creare gestori personalizzati, combinando uno dei precedenti. Inoltre, anche questi gestori possono essere utilizzati in combinazione.

In ASP.NET l'autorizzazione v5 ora fornisce semplice ruolo dichiarativa e un modello basato politica più ricca in cui l'autorizzazione è espressa in requisiti e gestori di valutare una pretesa nei confronti degli utenti requisiti. I controlli imperativi possono essere basati su policy semplici o sulle politiche che valutano sia l'identità dell'utente che le proprietà della risorsa a cui l'utente sta tentando di accedere.

+8

Buono a sapersi, ma non risponde affatto alla domanda. – Zero3

Problemi correlati