26
A
回答
1
Snap的snap-server
軟件包中沒有提供這種功能,我假設您是如何運行服務器的。
Buuuuut通過分叉或作爲一個單獨的模塊(您不得不復制一些代碼,因爲您需要的某些內部值不會導出)來構建並不困難。 bindHttps
,located 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。
更普遍的,我想知道的任何Haskell的Web框架是否提供了基於證書的客戶認證的支持。 – 2015-02-19 17:26:43
這是那種非答案,但作爲一種變通方法,您可以使用nginx的檢驗證書,並通過頭通過DN。 – 2015-11-10 21:54:04