2016-08-17 1 views
0

Ich habe einen twisted + flask https-Server eingerichtet, der auch eine zertifikatbasierte Clientauthentifizierung durchführt, indem Sie der Dokumentation auf der Twisted-Site here folgen. So weit, ist es gut.Zugriff auf das x509-Zertifikat des Clients über die twisted web WSGI-App

Zusätzlich zur Authentifizierung des Clients mit einem Zertifikat benötigt der Anwendungscode in der flask-App den Benutzernamen (der im Zertifikat des Clients x509 enthalten ist), um seine Aufgabe zu erfüllen. Ich konnte keine einfache Möglichkeit finden, auf diese Informationen zuzugreifen. Die Informationen (basierend auf der Dokumentation) scheinen sich zum Zeitpunkt der Authentifizierung im Objekt pyopenssl X509Name zu befinden, und ich benötige die Identität auf der Flaschebene jedes Mal, wenn ich eine Anfrage von diesem Client aus bearbeite.

Das Request Objekt Kolben bekommen bekam nicht diese Informationen zu haben (es sei denn, ich lese es falsch), also nehme ich an, dass ich einige Optionen auf der Twisted-Ebene ändern müssen, um sie an Kolben zu senden. Ich muss sie auch irgendwie aus der OpenSSL-Ebene herausholen.

Wie würden Sie das tun?

Antwort

0

Aktualisiert: Verwendung von HTTPChannel.allHeadersReceived anstelle von Protocol.dataReceived zur Unterstützung von Chunked-Anfragen.

können Sie HTTP-Header verwenden, um Verbindungsinformationen zu speichern: setzen sie in HTTPChannel.allHeadersReceived Verfahren und Abrufen von flask.request.headers, z.B .:

from twisted.application import internet, service 
from twisted.internet import reactor 
from twisted.web.http import HTTPChannel 
from twisted.web.server import Site 
from twisted.web.wsgi import WSGIResource 

from flask import Flask, request 

app = Flask('app') 

@app.route('/') 
def index(): 
    return 'User ID: %s' % request.headers['X-User-Id'] 

class MyHTTPChannel(HTTPChannel): 
    def allHeadersReceived(self): 
    user_id = 'my_user_id' 
    req = self.requests[-1] 
    req.requestHeaders.addRawHeader('X-User-Id', user_id) 
    HTTPChannel.allHeadersReceived(self) 

class MySite(Site): 
    protocol = MyHTTPChannel 

application = service.Application('myapplication') 
service = service.IServiceCollection(application) 

http_resource = WSGIResource(reactor, reactor.getThreadPool(), app) 
http_site = MySite(http_resource) 
internet.TCPServer(8008, http_site).setServiceParent(service) 

Ich bin nicht vertraut mit der Verwendung von Client-Zertifikaten in verdrehten. Ich nehme an, dass Sie seine Informationen in Protocol.transport abrufen können.

+0

danke für die Hilfe. Ich bin besorgt, dass diese data_received Implementierung davon ausgeht, dass wir nicht eine einzelne Anfrage in mehrere data_received Aufrufe aufteilen. Ist das eine gültige Annahme? – orm

+0

@orm Ja, du hast Recht, ich habe nicht darüber nachgedacht. Ein korrekterer Weg besteht darin, 'HTTPChannel.allHeadersReceived' zu überschreiben. Ich habe mein Codebeispiel aktualisiert. –

Verwandte Themen