2012-03-26 17 views
50

Come iniziare a codificare l'autenticazione utilizzando l'API Web ASP.NET in modo che sia multipiattaforma per supportare desktop, mobile e Web? Ho letto alcuni metodi per eseguire l'autenticazione RESTful, come l'uso di token nell'intestazione.Autenticazione cross platform tramite l'API Web ASP.NET

Esistono progetti di esempio che utilizzano questo metodo?

Domande:

  1. Se no come posso risolvere l'attributo [Authorize] di leggere il token?
  2. Come posso generare questo token? Non penso di poter usare l'autenticazione di form perché utilizza i cookie.
  3. Come si gestisce l'autorizzazione effettiva, il client invia password e nome utente non elaborati, quindi si genera il token o esiste un altro modo?
  4. Come gestisco quando il mio sito Web lo sta utilizzando? Ho sentito che questo è gestito in modo diverso rispetto a quando è utilizzato da un'app, come ottenere il dominio e autorizzarlo.

risposta

42

Penso che i token sarebbero una buona strada da percorrere. L'autenticazione basata su form si basa sui cookie per il web. Non è la situazione più idea per tutti i client non browser.

Quello che suggerirei è la creazione di un custom AuthorizationFilterAttribute e l'override del metodo OnAuthorization. In tale metodo, è possibile verificare l'esistenza di un token che è stato rilasciato al client dopo aver fornito credenziali valide. È possibile utilizzare questo attributo su qualsiasi metodo o controller che si desidera convalidare. Ecco un esempio si potrebbe riferimento

public class AuthorizeTokenAttribute : AuthorizationFilterAttribute 
{  
    public override void OnAuthorization(HttpActionContext actionContext) 
    { 
     if (actionContext != null) 
     {     
       if (!AuthorizeRequest(actionContext.ControllerContext.Request)) 
       { 
        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { RequestMessage = actionContext.ControllerContext.Request }; 
       } 
       return; 
     } 
    } 

    private bool AuthorizeRequest(System.Net.Http.HttpRequestMessage request) 
    { 
     bool authorized = false; 
     if (request.Headers.Contains(Constants.TOKEN_HEADER)) 
     {    
      var tokenValue = request.Headers.GetValues("TOKEN_HEADER"); 
      if (tokenValue.Count() == 1) { 
       var value = tokenValue.FirstOrDefault();    
       //Token validation logic here 
       //set authorized variable accordingly 
      }     
     } 
     return authorized; 
    } } 

TOKEN_HEADER è solo una stringa che rappresenta un header HTTP che il client deve passare di nuovo per le richieste autenticate.

Quindi cerchiamo di camminare attraverso di essa

  1. richieste dei client dati sicuri
  2. Cliente non è autorizzato, restituire una risposta con un codice di stato non autorizzato
  3. client invia le credenziali per l'autenticazione, che dovrebbe essere assicurato tramite HTTPS
  4. Una volta convalidato, il client riceve un token tramite un'intestazione HTTP, o qualsiasi cosa funzioni per voi
  5. Il client tenta di richiedere nuovamente i dati protetti, questa volta in allegato token alla richiesta
  6. AuthorizeTokenAttribute convaliderà il token e consentirà l'esecuzione dell'azione.

Inoltre, controlla questo post di John Petersen. Making your ASP.NET Web API’s secure

+1

Grazie, questo ha aiutato molto, come si consiglia di generare il token durante l'autenticazione? generare un guid e memorizzarlo per l'utente nel database? –

+0

che spetta a voi, suppongo. Puoi utilizzare un Guid o un hash o qualche tipo di valore univoco. dipende da cosa ha davvero senso la tua applicazione – cecilphillip

+0

nel tuo commento di codice che dici "imposta la variabile autorizzata di conseguenza" .... dove impostare la variabile autorizzata? sulla Request.Properties? Altrove? – ChrisCa

21

Esistono molti modi per autenticare gli utenti per un servizio REST. L'utilizzo di token è possibile, ma l'utilizzo di Basic Authentication è ancora più semplice e su base standard e multipiattaforma.

Non confondere authorization con authentication. L'attributo [Autorizza] riguarda esclusivamente l'autorizzazione, ma solo dopo che un utente è stato autenticato utilizzando un altro meccanismo. L'autorizzazione è completamente inutile senza prima fare un'autenticazione corretta.

La risorsa migliore da verificare è Dominick Baier che è un esperto in materia.

+0

Così sempre inviare il nome utente/password codificata nell'intestazione? –

+0

Per l'autenticazione di base è il modo per farlo sì. Usa HTTPS poiché la codifica è solo base64 che non è crittografia. – Maurice

+0

L'articolo di Dominick Baier è rotto –

2

Io uso un approccio molto semplice:

  1. definire un profilo di accesso con la sua AccessID unico e accessKey (ad esempio hashing MD5 valore GUID)
  2. negozio di tale profilo di accesso nel database
  3. ogni richiesta (GET/POST/etc.) Deve fornire accessId, queryHash (valore hash MD5 rappresenta la query) e firma (valore hash MD5 di queryHash + accessKey). Ovviamente il cliente deve mantenere l'accessKey in un posto sicuro !!!
  4. server riceve la richiesta controllerà l'AccessID e la firma utilizzando lo stesso algoritmo di calcolo di rifiutare o concedere l'accesso (autenticazione)
  5. ulteriore autorizzazione può essere fatto su base richiesta, tipo che utilizza il profilo di accesso

il servizio con questo approccio utilizzando la nuova API Web ASP.NET MVC può servire qualsiasi tipo di client: browser/javascript e nativo (desktop o mobile) ecc.

+3

Si potrebbe considerare qualcosa di più forte di MD5. A questo punto può essere rotto abbastanza velocemente, pensa minuti o ore. Dovresti fare l'hashing con qualcosa di più forte, come SHA256/512, o preferibilmente qualcosa di computazionalmente lento, come bCrypt. http://www.codinghorror.com/blog/2007/09/rainbow-hash-cracking.html http://www.codinghorror.com/blog/2012/04/speed-hashing.html http: // sicurezza. stackexchange.com/questions/211/ http://www.eweek.com/c/a/Security/SSL-Crack-Shows-You-Must-Advance-Your-Security/1/ – EBarr

+0

Ecco alcune informazioni utili @EBarr (Io ho fatto +1), ma penso che in questo caso sarebbe sicuro con MD5, considerando che quello che sta crittografando sarebbe troppo grande e oscuro per un tavolo arcobaleno. – Grinn

+0

@Le tabelle arcobaleno di Grinn sono così 2005 ;-). Sicuramente md5 probabilmente lo fa. Md5 può, tuttavia, essere brutalmente forzato in pochi minuti su una GPU forte in questi giorni. Ad esempio una scatola GPU amazon ec2 per pochi $$. – EBarr

0

U può utilizzare ActionFilterAttribute e sovrascrivere il metodo OnActionExecuting. Successivamente, registrare questo filtro in global.cs per applicare questo filtro per tutte le azioni come questa in Metodo avvio applicazione

var config = GlobalConfiguration.Configuration; config.Filters.Add (new CustomAuthAttribute());

{ namespace Customss { pubblici classe CustomAuthAttribute: ActionFilterAttribute

{ 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     // To inforce HTTPS if desired , else comment out the code 
     if (!String.Equals(actionContext.Request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase)) 
     { 
      actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest) 
      { 
       Content = new StringContent("HTTPS Required") 
      }; 
      return; 
     } 

     // get toekn from the header 

     var userToken = actionContext.Request.Headers.GetValues("UserToken"); 
     // Customer Logic to check the validity of the token. 
     // U can have some DB logic to check , custom STS behind or some loca cache used to compare the values 


    } 


} 

}}