2013-01-23 5 views
5

Ich habe eine node.js basierte Web-App, die sichere (https) Verbindungen vom Client erfordert. Was ich will ist, dass auf einigen Pfaden Client-Zertifikat-Authentifizierung erforderlich ist und auf anderen Pfaden nicht.Node.js Client-Zertifikat-Authentifizierung nur auf einigen Pfaden

Also zum Beispiel. Wenn der Benutzer zu https://www.example.com/main geht, benötigt der Server keine Client-Zertifikat-Authentifizierung (und der Browser fragt nichts). Wenn der Benutzer jedoch zu https://www.example.com/secure navigiert, ist die Clientzertifikatauthentifizierung erforderlich (und der Browser öffnet daraufhin einen Dialog zur Auswahl des zu verwendenden Zertifikats).

Wie kann ich dies erreichen? Ich bin in der Lage, Client-Zertifikat-Authentifizierung zu erzwingen, wenn ich requestCert:true und rejectUnauthorized:true zu https.createServer Optionen übergebe. Das Problem bei diesem Ansatz besteht darin, dass das Clientzertifikat für jeden Pfad erforderlich ist.

+0

Client-Zertifikate sind Teil des SSL-Handshakes; Ich bin mir nicht sicher, dass du tun kannst, was du willst. – Joe

+0

@Joe: Das war, wovor ich Angst hatte. Aber ich habe Websites gesehen, die das tun. Zunächst zeigen diese Apps eine Seite an, auf der der Benutzer aufgefordert wird, eine Smartcard einzufügen (wo sich das Clientzertifikat befindet). Wenn Sie auf "OK" klicken, leitet die App den Benutzer an einen anderen Pfad in der gleichen App um, der ein Clientzertifikat erfordert. An dieser Stelle zeigt der Browser einen Dialog an, in dem der Benutzer das verwendete Zertifikat auswählen kann. Also, gibt es vielleicht eine Möglichkeit, einen neuen Handshake innerhalb derselben Verbindung zu erzwingen? – Jukka

+0

Ich habe einen Weg, um dieses Problem zu umgehen, aber ich möchte es nicht verwenden. Eine Lösung besteht darin, zwei verschiedene Listener (verschiedene Ports) innerhalb derselben Anwendung zu verwenden. Der andere erfordert Client-Zertifikat-Authentifizierung und ein anderer nicht. Das Problem mit diesem Ansatz ist, dass ich dann nicht-Standard-Port für die zweite verwenden muss. Dies führt dazu, dass einige Kunden ihre Firewall neu konfigurieren müssen, um Verbindungen zu diesem Port zuzulassen. – Jukka

Antwort

0

Ich bin nicht sicher, ob ich genau verstehe, was Sie wollen .. aber basierend auf meinem Verständnis, wenn Sie Express verwenden, können Sie dieses Ding durch eine einfache Middleware verwalten .. In dieser Middleware können Sie jede Anfrage verfolgen kommt von http oder https durch diese

Eine HTTPS-Verbindung hat req.connection.encrypted (ein Objekt mit Informationen über die SSL-Verbindung). Eine HTTP-Verbindung hat keine req.connection.encrypted.

auch (aus der Dokumentation):

Mit HTTPS-Unterstützung verwenden request.connection.verifyPeer() und request.connection.getPeerCertificate() die Client-Authentifizierungsdaten zu erhalten.

Ich hoffe, das hilft ..

+1

Ich verwende Express Framework mit meiner Anwendung.Alle Verbindungen sind bereits https. Was ich will, ist, dass einige Pfade erfordern, dass ein Client mit Zertifikat und anderen Pfaden nicht authentifiziert wird. Ich benutze Knoten 0.8.18 und es scheint keine VerifyPeer-Methode in Verbindung zu haben. getPeerCertificate Methode gibt es und es funktioniert wie angenommen (aber es erzwingt nicht die Client-Zertifikat-Authentifizierung). – Jukka

1

ich hier gelandet, weil ich auf der gleichen Ausgabe arbeite und den Ansatz teilen Ich nehme. Für Endpunkte, bei denen der Benutzer sich mit einem gültigen Zertifikat authentifizieren muss, verwende ich einen benutzerdefinierten Pfad an Endpunkte, die das Zertifikat erfordern, und vergewissere mich, dass der Benutzer sich mit einem Zertifikat authentifiziert hat, wenn er auf einen Endpunkt zugreift, der diesem Pfad folgt (Express-App vorausgesetzt). dh:

app.use('/api/cert', function(req, res, next){ 
    //validate that any token passed in the request was generated for a valid 
    //cert login, otherwise reject request 

    //pseudo-code 
    if(isValidCertToken(req.authentication.token)) { 
     next(); //this will pass it on to the correct endpoint in the /api/cert/[whatever] chain 
    } else { 
     req.status(401).send({error: 'invalid login, cert required'}); 
    } 
}); 

Dies erfordert, dass Sie dem Benutzer die Möglichkeit zur Authentifizierung Zert mit, indem der requestCert Flag auf true zu ermöglichen, sondern auch andere Authentifizierungsmethoden zulassen, wenn der Benutzer nicht die „cert verwenden nicht wünscht erforderlich "Endpunkte, solange rejectUnauthorized bei der Einrichtung von https connecton auf false gesetzt ist.

+0

Dies bedeutet immer noch, dass der Benutzer aufgefordert wird, mit welchem ​​Zertifikat auf jedem Pfad zu wählen – DavidM

+0

Ja leider. Wir vermeiden dies, indem wir einen eigenständigen SSO-Server mit OAuth 2.0 verwenden, zu dem wir zur Authentifizierung weiterleiten. Flow: App -> [Benutzer klickt Login] -> direkt zu OAuth 2.0 Server -> [Benutzer aufgefordert für Cert] -> [Benutzer validiert basierend auf Cert] -> Umleiten an App mit Code zu Anfrage Token OR App -> [Benutzer klickt auf Login] -> direkt auf OAuth 2.0 Server -> [Benutzer zur Bestätigung aufgefordert] -> [Benutzer wählt Abbrechen für kein Zertifikat] -> Anmeldebildschirm wird angezeigt -> [Benutzer authentifiziert mit UN/PW] - > Weiterleitung zur App mit Code zum Anfordern des Tokens – weagle08

Verwandte Themen