2011-08-28 15 views
15

Attualmente sto scrivendo un'API di riposo in python con il pallone microframework. È un'API privata e si occupa dei dati utente. Ho intenzione di utilizzare questa API per creare un web e un'app per Android.Alla ricerca di un consiglio per proteggere un'API REST privata scritta in python-flask

Per ora utilizzo auth digest per proteggere i dati degli utenti privati. Ad esempio, se desideri pubblicare dati sul mio servizio con l'utente bob, fai una richiesta post su myapi/story/create e fornisci le credenziali di bob con lo schema digest.

Sono consapevole questa non è una buona soluzione, perché:
-Digest autenticazione non è sicuro
-Il client non è autenticato (? Come proteggere le richieste non attinenti con l'utente corrente, ad esempio creare un nuovo utente)

Ho letto un sacco di cose su oAuth ma l'autenticazione a 3 vie sembra eccessiva perché non ho intenzione di aprire la mia API a terze parti.
OAuth a 2 vie non si adatta perché fornisce solo l'autenticazione per i client e non per gli utenti.
Un altro problema con oAuth è che non ho trovato una guida completa per l'implementazione in Python. Ho trovato la libreria python-oauth2, ma non capisco l'esempio del server e non riesco a trovare ulteriore documentazione. Inoltre, sembra che molti aspetti di oAuth non siano trattati in questo esempio.

Quindi le mie domande sono:

  1. C'è schema alternativo (non oAuth) per l'autenticazione client e utente con un ragionevole livello di sicurezza?
  2. Se outh è la soluzione migliore:
    • Come saltare il processo di autorizzazione (perché gli utenti non dovranno autorizzare i client di terze parti)?
    • Esiste documentazione dettagliata per python-oauth2 o per qualsiasi altra libreria Python?

Qualsiasi aiuto o consiglio sarà apprezzato.

+0

Per quanto riguarda uno dei tuoi problemi, una gran parte dei principali siti di non lasciare che ti iscrivi attraverso cliente ecc, ti fanno iscrivere attraverso il loro sito web. Per quei siti che lo consentono, la loro chiamata API è effettivamente la stessa cosa del loro modulo di registrazione, quindi non importa se è sicuro o meno. –

risposta

7

La risposta più semplice è quello di esporre la vostra API solo tramite HTTPS, e quindi utilizzare l'autenticazione HTTP di base. Non penso ci sia davvero alcun motivo per preoccuparsi di Digest. L'autenticazione di base non è sicura, ma viene inviata ad ogni richiesta, quindi non dovrai mai preoccuparti che la tua autenticazione vada in stallo o altro. Tunneling su HTTPS, hai una connessione sicura.

Se si desidera autenticare il client, è possibile utilizzare i certificati client SSL.Detto questo, in generale è piuttosto difficile bloccare il client da utenti malintenzionati, quindi prenderei in considerazione l'idea di rendere le funzioni di registrazione accessibili e proteggersi da DOS ecc. Tramite verifica dell'account out-of-band.

+1

Ho lavorato a questo progetto durante il mio tempo libero e purtroppo l'ho fermato. Ho usato oauth a 3 zampe. Non è stato facile da implementare e dal momento che l'API era privata, non c'erano vantaggi significativi rispetto ai certificati client di base + https +. Non ho provato ma la tua risposta risponde alla parte più importante della domanda (alternativa a oAuth), quindi l'ho contrassegnata come accettata. Grazie. –

3

Hai già considerato l'utilizzo dell'autenticazione di base?

Non ho ancora utilizzato il framework menzionato, ma ho utilizzato l'autenticazione di base per proteggere alcuni URL in un'app basata su web.py e ha funzionato correttamente.

Fondamentalmente, è possibile utilizzare un token in base64 che è in realtà un heeader HTTP standard.

Forse questo esempio consente di:

class Login: 

    def GET(self): 
     auth = web.ctx.env.get('HTTP_AUTHORIZATION') 
     authreq = False 
     if auth is None: 
      authreq = True 
     else: 
      auth = re.sub('^Basic ','',auth) 
      username,password = base64.decodestring(auth).split(':') 
      if (username,password) in settings.allowed: 
       raise web.seeother('/eai') 
      else: 
       authreq = True 
     if authreq: 
      web.header('WWW-Authenticate','Basic realm="Auth example"') 
      web.ctx.status = '401 Unauthorized' 
      return 
+1

Serbatoi per la tua risposta, apprezzo il tuo coinvolgimento :) ma ci sono esattamente gli stessi problemi con l'autenticazione di base o Digest. Come posso autenticare utente e cliente nella stessa richiesta? –

0

Se si è interessati all'autenticazione di base, ecco un attributo rapido che è possibile utilizzare per decorare i gestori http://www.varunpant.com/posts/basic-authentication-in-web-py-via-attribute. Questo esempio è scritto principalmente nel contesto web.py, ma suppongo che possa essere facilmente modificato.

def check_auth(username, password): 
    return username == 'username' and password == 'password' 


def requires_auth(f): 
    @wraps(f)  
    def decorated(*args, **kwargs):   
     auth = web.ctx.env['HTTP_AUTHORIZATION'] if 'HTTP_AUTHORIZATION' in web.ctx.env else None 
     if auth: 
      auth = re.sub('^Basic ', '', auth) 
      username, password = base64.decodestring(auth).split(':') 
     if not auth or not check_auth(username, password): 
      web.header('WWW-Authenticate', 'Basic realm="admin"') 
      web.ctx.status = '401 Unauthorized' 
      return 

     return f(*args, **kwargs) 

    return decorated