如何使用Snap检查客户端证书

J. *_*son 26 ssl haskell happstack haskell-snap-framework

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

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

hao*_*hao 2

您在 Snap 中无法使用此功能snap-server,我假设这就是您运行服务器的方式。

\n\n

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

\n\n

我们幸运的是 OpenSSL 完全支持客户端证书。您只需将验证模式设置为SSL_VERIFY_PEER。您还可以摆弄其他旋钮。您还必须确保安装证书链来实际验证客户端证书。信任链和所有爵士乐。作为参考,请参阅nginx 是如何实现的

\n\n

更好的是,这个函数作为function公开。您会注意到Snap 的定义中存在这一点。您所要做的就是复制或分叉该模块并引入您的调用。HsOpenSSLcontextSetVerificationMode :: SSLContext -> VerificationMode -> IO ()ctx :: SSLContextbindHttps

\n\n

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

\n\n
\xc2\xb1 % diff -u /tmp/{old,new}\n--- /tmp/old    2016-04-11 11:02:42.000000000 -0400\n+++ /tmp/new    2016-04-11 11:02:56.000000000 -0400\n@@ -19,6 +19,7 @@\n\n      ctx <- SSL.context\n      SSL.contextSetPrivateKeyFile ctx key\n+     SSL.contextSetVerificationMode ctx (SSL.VerifyPeer True True (Just (\\_ _ -> return True)))\n      if chainCert\n        then SSL.contextSetCertificateChainFile ctx cert\n        else SSL.contextSetCertificateFile ctx cert\n
Run Code Online (Sandbox Code Playgroud)\n\n

第一个布尔值告诉 OpenSSL 如果不存在客户端证书则失败。第二个布尔值告诉 OpenSSL 仅在第一次请求时需要客户端证书,而在重新协商时不再需要。第三个值是回调。我认为正确的做法是在回调中返回 True。无论如何,这就是nginx 所做的事情。

\n