2013-03-19 123 views
26

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

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

+1

更普遍的,我想知道的任何Haskell的Web框架是否提供了基于证书的客户认证的支持。 – 2015-02-19 17:26:43

+0

这是那种非答案,但作为一种变通方法,您可以使用nginx的检验证书,并通过头通过DN。 – 2015-11-10 21:54:04

回答

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

更妙的是,这个功能是作为HsOpenSSL功能contextSetVerificationMode :: SSLContext -> VerificationMode -> IO()exposed。您会注意到Snap的bindHttps的定义中存在ctx :: SSLContext。您只需复制或分发该模块并引入您的呼叫即可。

它看起来像这样(待验证码警报):

± % 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