【问题标题】:How to make httpc request and attach client certificate?如何发出 httpc 请求并附加客户端证书?
【发布时间】:2021-05-29 07:41:18
【问题描述】:

我有一个 IIS 托管站点,该站点需要将客户端证书附加到任何传入请求。我正在尝试从 Erlang 发出请求,但无法弄清楚如何将客户端附加到传出的 httpc 请求。我的示例代码:

inets:start(),
ssl:start(),
httpc:request(get, {"https://my-iis-host.org/api/endpoint?parm1=foobar", []}, [{ssl, [{cacertfile, "/path/to/my/cert.pem"}]}], []) . 

从服务器返回 403.7 响应。我确定证书很好,因为我可以使用 curl 并成功拨打相同的电话并获得成功的响应:

curl -v --cert /path/to/my/cert.pem "https://my-iis-host.org/api/endpoint?parm1=foobar"

我认为我的 erlang 调用是错误的,它实际上并没有将客户端证书附加到请求中,但它应该如何工作?感谢您的帮助!

编辑:最终我试图解决的问题实际上是将POST 数据发送到端点并附加客户端证书。为了简单起见,我用GET 复制了它,但想分享我完整的POST 示例,以防其他人遇到相同的问题:

inets:start(),
ssl:start(),
Body = "{'name':'value','name1':'value1'}",
Request = {"https://my-iis-host.org/api/endpoint", [], "application/json", Body},
httpc:request(post, Request, [{ssl, [{certfile, "/path/to/my/cert.pem"}]}], []) . 

【问题讨论】:

  • 你为什么不为你的 curl 请求使用--cacert 选项? 我认为我的 erlang 调用是错误的,它实际上并未将客户端证书附加到请求中, -- 您如何确定?
  • 这些都是公平的问题。对于curl,我知道--cert 附加了客户端证书。据我在 erlang 文档 (erlang.org/doc/man/ssl.html#type-client_cafile) 中所知,cacertfile 似乎是最接近的。但这可能是错误的,因为它对我不起作用。而且我不确定客户端证书没有被附加,除了我得到的 407.3 响应,并且证书与 curl 一起成功工作。您知道在 erlang 中将客户端证书附加到请求的正确方法吗?

标签: erlang


【解决方案1】:

我认为您需要使用certfile 选项而不是cacertfile。试试

httpc:request(get, {"https://my-iis-host.org/api/endpoint?parm1=foobar", []}, [{ssl, [{certfile, "/path/to/my/cert.pem"}]}], []).` 

【讨论】:

  • 谢谢!这个简单的例子让我上路了!
【解决方案2】:

curl 提供以下选项:

--cert
--cacert

您选择使用--cert 选项,并且您的 curl 请求成功。

erlang 列出了ssloption() 的以下选项:

ssloption() = {验证,验证类型()} | {verify_fun, {fun(), term()}} | {fail_if_no_peer_cert, boolean()} {depth, integer()} | {证书, der_encoded()}| {certfile, path()} | {键,{'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey' |'PrivateKeyInfo', der_encoded()}} | {密钥文件,路径()} | {密码,字符串()} | {cacerts,[der_encoded()]} | {cacertfile, path()} | |{dh, der_encoded()} | {dhfile,路径()} | {密码,密码()} | {user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity, {string(), string()}} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {重用会话, fun()} {next_protocols_advertised, [binary()]} | {client_preferred_next_protocols, {client |服务器,[二进制()]} | {客户 |服务器,[二进制()],二进制()}} | {log_alert, boolean()} | {server_name_indication,主机名()|禁用}

为了与您的 curl 请求保持一致,人们会认为您会选择 {certfile, path()}

【讨论】:

  • 谢谢,certfile 似乎确实是罪魁祸首。有人会认为在其中搜索“客户端证书”时文档可能更清楚,或者它也可能提供具体的使用示例......我是 erlang 新手,但手册页留下了一些想要的,恕我直言...
  • @PeterTirrell, certfile 似乎确实是罪魁祸首---好吧,你为什么不发布整个罪魁祸首是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 2018-08-15
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
相关资源
最近更新 更多