responsabilità
Prima di iniziare vorrei far notare il commento di @Emanuel Ey. Che vorresti considerare se questo è stato fatto prima su un server di produzione o di sviluppo. Per esempio; se si utilizza Apache WebServer, il componente HTTPS può essere eseguito da Apache. L'unica cosa che farebbe diversamente è passare attraverso i dettagli del certificato come opzioni e l'app del server dovrebbe quindi verificare il numero di serie all'interno dell'app stessa.
è possibile
Ma il modo in cui è possibile non è considerata buona pratica di programmazione. Sfortunatamente, non è accessibile da flask.request
e non è possibile con il pacchetto Flask. Tuttavia, Flask usa Werkzeug ed è possibile correggendo il pacchetto werkzeug.serving
dove scriverà il tuo codice principale. Non è raccomandato perché potresti voler aggiornare Flask o Werkzeug in un secondo momento e la tua patch potrebbe rompersi e necessitare di essere riprogrammata. cioè da 0,9 a 1,0.
Fornisce una soluzione senza utilizzare un server web. Ma raccomanderei la combinazione di server Web/variabile di ambiente. È una pratica più pulita e relativamente buona.
Ho eseguito alcuni test per verificare se è facile da implementare. Sono stato in grado di confermare che questo metodo può funzionare utilizzando l'ultimo codice di sviluppo di sviluppo 'Werkzeug-0.10_devdev_20141223-py2.7'.
Probabilmente vorrete verificare il numero di serie (numero seme) trovato in ciascun certificato (e forse anche qualche altra variabile). Come forse saprai, la serie è unica per ogni certificato e viene determinata durante il processo di generazione del certificato da parte tua sul lato server. Aiuta a memorizzare questo insieme al record del cliente e le informazioni sul certificato (se necessario) al fine di verificare in seguito il numero di serie del certificato del cliente. Nota: potrebbe richiedere delle modifiche tra esadecimale e decimale base 10.
Werkzeug dev_2014122
Quello che ho fatto è stato quello di aggiungere le seguenti opzioni alla chiamata werkzeug.serving.BaseWSGIServer.__init__
-wrap_socket()
.
Utilizzare questi; server_side=True, ca_certs= '/etc/apache2/ssl/ca.pem', cert_reqs=ssl.CERT_REQUIRED
- ca_certs: Usare questo per verificare contro, questo è il CERT CA utilizzato per generare i certificati client)
- ssl.CERT_REQUIRED: richiedere la verifica del certificato client contro ca_certs
Nota: Se il certificato client non supera la verifica iniziale, non sarà possibile recuperare il certificato client. Sarà None.
Poi nella mia classe di test Flask ho patchato verify_request
dove
def verify_request(self, request, client_address):
cert = request.getpeercert(True)
raw = decoder.decode(cert)[0]
print "Serial Number of your certificate is: % " % str(raw[0][1])
# todo: do checks & if serial no is ok then return true
return True
werkzeug.serving.BaseWSGIServer.verify_request = verify_request
Questo si è rivelato è possibile ma probabilmente vuole indagare i gestori delle richieste della classe HTTPServer che il BaseWSGIServer eredita da trovare un modo migliore per richiamare o ignorare.
Werkzeug 0.9.x
Se si utilizza Werkzeug 0.9.x Sto assumendo che si sta utilizzando l'importazione from OpenSSL import SSL
. vedere lo snippet di codice here. Non ho provato questo.
Alcune delle chiamate a cui potresti essere interessato per questa versione sarebbero; - Context.set_verify(mode, callback)
- Connection.get_peer_certificate()
Chiarimento
Quello che non capisco è il vostro riferimento all'invio di una CSR durante la prima stretta di mano. Se questo è il tuo processo di generazione di certificati client, potresti voler ripensare a come lo fai nel contesto del tuo sistema e dell'ambiente. Se potessi avere qualche informazione in più potrei commentare ulteriormente ..
Inoltre, "stretta di mano" in un contesto SSL/TLS generalmente si riferisce all'azione di creare la connessione protetta in primo luogo utilizzando un certificato esistente. Immediatamente dopo l'handshaking, parlando liberamente, viene stabilita una connessione.
Perché è necessario eseguire l'autenticazione dall'altra parte? A meno che il client non stia ascoltando le connessioni non dovrebbe essere necessario. –
@ sshanshank124 Vorrei autenticare ciascun client in base al certificato client ed elaborare la sua richiesta di conseguenza – nishi
TLS/SSL è una funzionalità che fa parte del server web. La tua domanda implica che stai utilizzando il server di sviluppo di Flask invece di un server di produzione per eseguire la tua app. Questa è probabilmente una cattiva idea. Dai un'occhiata a http://flask.pocoo.org/docs/0.10/deploying/ –