2012-04-13 14 views
6

Este programa de prueba se conecta a un servidor https y obtiene algo de contenido. Revisé mi servidor en navegadores y con curl y el certificado funciona correctamente. Si ejecuto Curl para tomar datos del servidor, se queja correctamente de que se desconoce el certificado a menos que lo transfiera con --cacert o apague la seguridad con -k.Mi cliente https de node.js siempre funciona independientemente de la validez del certificado

Así que el problema que estoy teniendo es que, aunque creo que mi cliente debería estar haciendo autenticación de certificados y le digo dónde está el certificado público, siempre funciona. Si elimino la opción ca: para que no tenga idea de qué es el certificado del servidor, funciona silenciosamente. Me gustaría detectar el error de autenticación, pero parece que no puedo hacerlo.

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(); 

Respuesta

10

Con el fin de hacer este trabajo que necesitaba para actualizar a v0.7.8 (aunque cualquier v0.7 debe estar bien), donde la funcionalidad rejectUnauthorized se ha añadido a https.get

Esta combinación de opciones es necesario:

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') ] 

Ahora, si la autenticación falla, obtendrá un evento de 'error' y la solicitud no continuará.

Véase el https.request documentation para obtener más información sobre cómo hacer su propio Agente

La corrección de errores se cometió en este cambio: https://github.com/joyent/node/commit/f8c335d0

+1

rejectUnauthorized fue agregado en la versión 0.7.0 –

+2

En cuanto a los documentos: http://nodejs.org/api/tls.html, no hay indicación de que 'rejectUnauthorized' se haya agregado para el cliente ... para el servidor sí pero no para el cliente. ¿Puedes por favor ponerme en el camino correcto aquí? ¿Estoy mirando documentos desactualizados aquí? – pulkitsinghal

+0

La lista de cambios se encuentra en la respuesta anterior. El problema fue rastreado aquí https://github.com/joyent/node/issues/2247 No he visto si la documentación fue actualizada, lo siento. – justinhj

4

Según el documentation de https.request, la opción de ca tanto https.get y https.request es una opción en tls.connect. La documentación de las opciones a la función tls.connect módulo afirma:

ca: Un conjunto de cadenas o tampones de certificados de confianza. Si esto es omitido, se usarán varias CA "raíz" bien conocidas, como VeriSign. Estos se usan para autorizar conexiones.

de excavación en la fuente de Node.js, los CERT raíz empleados se pueden encontrar aquí: https://github.com/joyent/node/blob/master/src/node_root_certs.h

Así que en resumen, sin cert autoridad proporcionada como una opción para el módulo https.gettls intentará autenticar el conexión usando la lista de certs de raíz de todos modos.

+1

Eso es buena información gracias. No me ayuda aquí, porque estoy usando mi propio certificado autofirmado. Esperaría que la conexión solo funcione si paso mi certificado, pero funciona de cualquier manera. – justinhj

+0

@ Перо ¿hay alguna forma de combinar el certificado del servidor y no perder las CA raíz? Ej: 'ca: [fs.readFileSync ('myServerCert.pem '), node_root_certs.h] '¿Cuál sería la sintaxis para acceder a la constante en el archivo de encabezado? – pulkitsinghal

1

En V 0.6.15 necesita explicitly check si la validación del certificado ha pasado o no.

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

Parece prometedor, pero x.authorized no está definido – justinhj

+0

@justinhj. He reparado el código en la respuesta. –

+0

Presumiblemente, esto está destinado a colocarse en la función de devolución de llamada. Lamentablemente, esto no impide que la solicitud se realice cuando el certificado no es de confianza, simplemente le dice una vez que está hecho (es posible que haya filtrado las credenciales de autenticación para entonces, por ejemplo). – Bruno

2

Lo hago en la NGP, utilizando el módulo request. Funciona así:

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) { ... }) 

El evento de error se generará si el ssl no es válido.

Cuestiones relacionadas