【问题标题】:How can I check the client certificate using Snap如何使用 Snap 检查客户端证书
【发布时间】:2013-03-07 14:30:51
【问题描述】:

我知道它很少使用,但是可以在 Snap 中访问客户端证书吗?

如果没有,是否可以使用不同的网络堆栈?

【问题讨论】:

  • 更一般地说,我想知道是否有任何 Haskell Web 框架提供对基于证书的客户端身份验证的支持。
  • 这是一个无法回答的问题,但作为一种解决方法,您可以使用 nginx 验证证书并通过标头传递 DN。

标签: haskell ssl haskell-snap-framework happstack


【解决方案1】:

这在 Snap 的 snap-server 包中对您不可用,我假设这是您运行服务器的方式。

Buuuuut 构建起来并不难,无论是通过分叉还是作为一个单独的模块(不过,您必须复制一些代码,因为您需要的一些内部值不会被导出)。 bindHttpslocated in Snap.Internal.Http.Server.TLS 是您想要定位的目标。该函数主要是对来自HsOpenSSL 库的OpenSSL.Session 调用的封装,它本身是OpenSSL 库的松散封装。

幸运的是,OpenSSL 完全支持客户端证书。您只需将verification mode 设置为SSL_VERIFY_PEER。还有其他旋钮你也可以摆弄。您还必须确保安装证书链以实际验证客户端证书。信任链和所有爵士乐。供参考,看如何nginx does it

更好的是,这个函数是exposed in HsOpenSSL 作为函数contextSetVerificationMode :: SSLContext -> VerificationMode -> IO ()。您会注意到 ctx :: SSLContext 存在于 Snap 的 bindHttps 的定义中。您所要做的就是复制或分叉该模块并介绍您的调用。

它看起来像这样(未经验证的代码警报):

± % diff -u /tmp/{old,new}
--- /tmp/old    2016-04-11 11:02:42.000000000 -0400
+++ /tmp/new    2016-04-11 11:02:56.000000000 -0400
@@ -19,6 +19,7 @@

      ctx <- SSL.context
      SSL.contextSetPrivateKeyFile ctx key
+     SSL.contextSetVerificationMode ctx (SSL.VerifyPeer True True (Just (\_ _ -> return True)))
      if chainCert
        then SSL.contextSetCertificateChainFile ctx cert
        else SSL.contextSetCertificateFile ctx cert

如果没有客户端证书,第一个布尔值告诉 OpenSSL 失败。第二个布尔值告诉 OpenSSL 客户端证书仅在第一次请求时需要,在重新协商时不再需要。第三个值是回调。我认为正确的做法是在回调中返回 True 。反正就是nginx does

【讨论】:

    猜你喜欢
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2012-01-08
    • 2020-04-20
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多