2012-04-13 9 views
6

Questo programma di test si connette a un server HTTPS e ottiene alcuni contenuti. Ho controllato il mio server nei browser e con arricciatura e il certificato funziona correttamente. Se eseguo curl per prelevare dati dal server, si lamenta correttamente del fatto che il certificato sia sconosciuto a meno che non lo passi con --cacert o disattivi la sicurezza con -k.I miei node.js https client funziona sempre indipendentemente dalla validità del certificato

Così il problema che sto avendo è che anche se penso che il mio cliente dovrebbe fare l'autenticazione dei certificati e sto dicendo che se il certificato pubblico è, funziona sempre. Se rimuovo l'opzione ca: quindi non ha idea di cosa sia il certificato dal server, quindi funziona silenziosamente. Vorrei rilevare l'errore di autenticazione ma non riesco a farlo.

var https = require('https'); 
var fs = require('fs'); 

function main() { 

     var data = ''; 

     var get = https.get({ 
     path: '/', 
     host: 'localhost', 
     port: 8000, 
     agent: false, 
     ca: [ fs.readFileSync('https_simple/cacert.pem') ] 

     }, function(x) { 

     x.setEncoding('utf8'); 
     x.on('data', function(c) {data += c}); 
     x.on('error', function(e) { 
      throw e; 
     }); 
     x.on('end', function() { 
      console.log('Hai!. Here is the response:'); 
      console.log(data); 
     }); 

     }); 

     get.on('error', function(e) {throw e}); 

     get.end(); 

    } 

main(); 

risposta

10

Al fine di rendere questo lavoro avevo bisogno di effettuare l'aggiornamento a v0.7.8 (anche se qualsiasi v0.7 dovrebbe andare bene) in cui è stata aggiunta la funzionalità rejectUnauthorized a https.get

Questa combinazione di opzioni è necessario:

agent: false, // or you can supply your own agent, but if you don't you must set to false 
rejectUnauthorized: true, 
ca: [ fs.readFileSync('https_simple/cacert.pem') ] 

Ora se l'autenticazione fallisce si otterrà un evento di 'errore' e la richiesta non andrà avanti.

Vedi l'https.request documentation per i dettagli su fare il proprio agente

La correzione bug è stato impegnato in questo cambiamento: https://github.com/joyent/node/commit/f8c335d0

+1

rejectUnauthorized è stato aggiunto nella versione 0.7.0 –

+2

Guardando i documenti: http://nodejs.org/api/tls.html, non c'è indicazione che "rejectUnauthorized" è stato aggiunto per client ... per server sì ma non client. .. puoi per favore ambientarmi sulla strada giusta qui? Sto guardando documenti scaduti qui? – pulkitsinghal

+0

L'elenco delle modifiche si trova nella risposta sopra. Il problema è stato tracciato qui https://github.com/joyent/node/issues/2247 Non ho ancora visto se la documentazione è stata aggiornata, mi dispiace. – justinhj

4

Come per la documentation per https.request, l'opzione ca sia https.get e https.request è un'opzione da tls.connect. La documentazione per le opzioni alla funzione modulo di tls.connect afferma:

ca: Un array di stringhe o buffer di certificati attendibili. Se questo è omessa alcuni noti "root" CA sarà utilizzato, come VeriSign. Questi sono usati per autorizzare le connessioni.

Scavando nella fonte node.js, i certificati di origine utilizzati possono essere trovate qui: https://github.com/joyent/node/blob/master/src/node_root_certs.h

Così, in breve, senza cert autorità fornito come opzione per https.get modulo tls tenterà di autenticare il connessione usando comunque la lista dei certificati di root.

+1

questo è un bene informazioni, grazie. Non mi aiuta qui, perché sto usando il mio certificato autofirmato. Mi aspetto che la connessione funzioni solo se passo il mio certificato, ma funziona in entrambi i modi. – justinhj

+0

@ Перо C'è qualche modo per combinare il CERT del server e non perdere la radice CA? Es: 'ca: [fs.readFileSync ('myServerCert.pem '), node_root_certs.h] 'Quale sarebbe la sintassi per accedere alla costante nel file di intestazione? – pulkitsinghal

1

In V 0.6.15 è necessario explicitly check se la convalida del certificato superato o meno.

if (x.connection.authorized === false) {  
    console.log('SSL Authentication failed'); 
} else if (x.connection.authorized === true) {  
    console.log('SSL Authentication succeeded'); 
} 
+0

Sembra promettente ma x.authorized non è definito – justinhj

+0

@justinhj, ho corretto il codice nella risposta. –

+0

Presumibilmente, è pensato per essere inserito nella funzione di callback. Sfortunatamente, questo non impedisce che la richiesta venga fatta quando il certificato non è attendibile, ma ti dice solo una volta che è stato fatto (potresti avere tra l'altro perso le credenziali di autenticazione, ad esempio). – Bruno

2

faccio questo in NPM, utilizzando il modulo request. Funziona così:

var cacert = ... // in npm, this is a config setting 
var request = require("request") 
request.get({ url: "https://...", 
       ca: cacert, 
       strictSSL: true }) 
    .on("response", function (resp) { ... }) 
    .on("error", function (er) { ... }) 

L'evento di errore verrà generato se ssl non è valido.