How to make a request with client certificate in Rust

蓝咒 提交于 2020-01-11 11:36:11

问题


I have a project with microservices deployed in Bluemix with Docker containers. All microservices are written in Java and the communication is using JKS files.

I also developed a microservice in Node.js with Express.js. To consume the other microservices, I used the Request module with option.agentOptions feature and a pfx file, like this:

var options = {
        uri: config.get("https://www.example.com/ms/service"),
        method: 'POST',
        body: data,
        json: true,
        headers: {
            'Content-Type': 'application/json; charset=UTF-8'
        },
        agentOptions: {
            pfx: fs.readFileSync(config.get("/path/to/file.pfx")),
            passphrase: config.get("passphraseText"),
            servername: config.get("serverName")
        }
    };

request(options, function (error, response, data) {
     //handing response
});

I tried to use the Solicit crate with default example for HTTPS but it fails with:

4 | use solicit::http::client::tls::TlsConnector;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Could not find `tls` in `client`

I couldnt find another crate, library or framework for made it, how can I make this requests?


EDIT

Apparently Solicit isn't an alternative for its lack of maintenance so it is no longer an alternative solution to this question, Here's the reason.


回答1:


At the moment, you should prefer the hyper client over solicit. The latter has not been updated since 2015, and hyper is being given better maintenance. Add hyper = "0.10.10", and hyper-native-tls = "0.2.2" to your dependencies. For specifying the client certificate to use, we can leverage the features of native_tls. In particular, TlsConnectorBuilder and Pkcs12 are what you're looking for.

use std::fs::File;
use std::io::Read;
use hyper::client::Client;
use hyper::net::HttpsConnector;
use hyper_native_tls::NativeTlsClient;
use hyper_native_tls::native_tls::{TlsConnector, Pkcs12};

// fetch the PKCS12 client certificate
let cert = {
    let cert_file = File::open("/path/to/cert.pfx")?;
    let mut cert_raw = Vec::new();
    cert_file.read_to_end(&mut cert_raw)?;
    Pkcs12::from_der(&cert_raw, "mypassword")?
};

// specify the TLS connection with the builder pattern 
let tls_conn = TlsConnector::builder()
    .identity(cert)?
    .build()?;
let ssl = NativeTlsClient::from(tls_conn)?;
let https_conn = HttpsConnector::new(ssl);

// proceed as usual
let client = Client::with_connector(https_conn);
let endpoint = "https://www.example.com/ms/service");
let resp = client.get(endpoint).send()?;

In solicit, the documentation states that the tls submodule was only available when the "tls" feature is enabled for this dependency. Nevertheless, this would lead to further dependency conflicts (see Why does solicit 0.4.4 attempt to use openssl 0.9.12 even though I have openssl 0.7.14 in my Cargo.toml?). Sticking to hyper instead of solicit is a much safer choice.



来源:https://stackoverflow.com/questions/44059266/how-to-make-a-request-with-client-certificate-in-rust

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!