29

Sto implementando un servizio web RESTful utilizzando ASP.Net Web Api. Ho concluso l'utilizzo dell'autenticazione di base + SSL per eseguire la parte di autenticazione. Qual è il modo migliore/corretto per implementarlo?Web service RESTful di ASP.net + Autenticazione di base

Il mio primo tentativo è stato quello di farlo manualmente, analizzando l'intestazione Autorizzazione, decodificando e verificando l'utente sul mio database. Funziona, ma mi chiedo se mi manca qualcosa.

Ho visto alcune soluzioni che utilizzano ruoli e principi utente. Mentre non sono sicuro di ciò che effettivamente fanno, sono quasi sicuro che non avrò bisogno di questi, dal momento che nel mio database definisco i miei utenti e i loro ruoli.

Anche ciò che non ho ancora completamente compreso, è se i consumatori del servizio devono inviare le credenziali con ogni richiesta o sono in qualche modo nella cache. Il mio servizio dovrebbe fare qualcosa in modo che ciò accada, o è completamente a carico del consumatore di gestirlo?

E un'ultima domanda sui client che fanno richieste con javascript. Ci sarebbero problemi di "richiesta di dominio incrociato" se provassero ad usare il servizio?

risposta

25

Jamie Kurtze fornisce una buona spiegazione di utilizzare l'autenticazione di base qui ASP.NET Web API REST Security Basics

Dalla mia comprensione, se si desidera che le richieste siano apolidi, ciascuna richiesta verrà richiesta e il campo Autenticazione da impostare

Jamie Kurtze avvolge il codice necessario in una classe derivata da DelegateHandler, mentre Rick Strahl controlla se la chiamata è valida utilizzando un filtro. Si può leggere di più al suo post sul blog su questo argomento in A WebAPI Basic Authentication Authorization Filter

+0

Ciao, quando ho scritto la domanda, non è chiaro nella mia mente come vengono utilizzati i Principali e i ruoli (e come sono collegati ai miei utenti). Quello che faccio ora è utilizzare l'intestazione di autenticazione per passare le credenziali e un modulo Http per controllarne uniformemente. Darò comunque un'occhiata ai tuoi link quando avrò un po 'di tempo. – alfoks

+0

La mia implementazione funziona bene ora, ma questi sono buoni collegamenti per i futuri lettori. – alfoks

+1

Il primo collegamento che ASP.NET Web Api REST Nozioni di base sulla protezione è inattivo –

1
+0

Questi collegamenti in realtà non rispondono alle mie domande. Solo la prima domanda potrebbe essere, ma si riferiscono alla configurazione di una libreria di sicurezza di terze parti. A causa della mancanza di tempo, voglio evitare di usare più librerie. – alfoks

21

utilizzo dell'autenticazione di base per l'iniziale (login) richiesta con l'aggiunta di un attributo [BasicHttpAuthorize] alle appropriate controllori/metodi. Specificare il numero Users e Roles con l'attributo se lo si desidera. Definire BasicHttpAuthorizeAttribute come specializzata AuthorizeAttribute come questo:

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool IsAuthorized(HttpActionContext actionContext) 
    { 
     if (Thread.CurrentPrincipal.Identity.Name.Length == 0) { // If an identity has not already been established by other means: 
      AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization; 
      if (string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0) { 
       string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter)); 
       int separatorIndex = credentials.IndexOf(':'); 
       if (separatorIndex >= 0) { 
        string userName = credentials.Substring(0, separatorIndex); 
        string password = credentials.Substring(separatorIndex + 1); 
        if (Membership.ValidateUser(userName, password)) 
         Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), System.Web.Security.Roles.Provider.GetRolesForUser(userName)); 
       } 
      } 
     } 
     return base.IsAuthorized(actionContext); 
    } 
} 

Avere la risposta iniziale includere una chiave API per l'utente. Utilizzare la chiave API per le chiamate successive. In questo modo, l'autenticazione del client rimane valida anche se l'utente cambia nome utente o password. Tuttavia, quando si modifica la password, dare all'utente un'opzione per "disconnettere i client", che si implementa eliminando la chiave API sul server.

+0

Ho già risolto il problema ma grazie per aver risposto. Trovo più facile passare, in tutte le chiamate API, il nome utente e la password nell'intestazione Autorizzazione, invece di utilizzare l'approccio token che suggerisci. – alfoks

+0

@Edward Grazie mille per il tuo post, trovo il massimo aiuto. Quale utente e meccanismo di ruolo stai usando in questo esempio? Perché vedo che crei un nuovo GenericPrinsiple. Potrebbe interessarti ad elaborare il modo in cui integro la tua soluzione in un nuovo progetto web API vuoto. – Zapnologica

+0

@Zapnologica Questo codice utilizza il vecchio modello di identità di appartenenza utilizzato da Microsoft prima di VS2013. I modelli con VS2013 utilizzano il nuovo sistema di identità basato su OWIN, che esegue un'autenticazione utente/password personalizzata seguita dall'utilizzo di token al portatore, eliminando la necessità di BasicHttpAuthorize. –

Problemi correlati