2013-03-19 124 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