haskell amqp x509客户端身份验证
我一直在想如何在haskell amqp x509客户端身份验证,haskell,amqp,x509,Haskell,Amqp,X509,我一直在想如何在Network.AMQP中使用x509客户端身份验证。似乎我需要创建一个AMQP.ConnectionOpts,其中包括cotlsettings参数,如下所示: import qualified Network.AMQP as AMQP import Network.Connection let opts = AMQP.ConnectionOpts { .. , coTLSSettings = Just $ AMQP.TLSCustom $ ... } 此时(省略号
Network.AMQP
中使用x509客户端身份验证。似乎我需要创建一个AMQP.ConnectionOpts
,其中包括cotlsettings
参数,如下所示:
import qualified Network.AMQP as AMQP
import Network.Connection
let opts = AMQP.ConnectionOpts {
..
, coTLSSettings = Just $ AMQP.TLSCustom $ ...
}
此时(省略号),在阅读了一些Network.Connection
文档之后(这超出了我的深度),它开始看起来非常复杂。我左思右想,我是否走上了正确的道路
那么,我的问题是:如何轻松实现x509客户端身份验证?如果答案是“你不能”,那么有人知道我在哪里可以找到使用Network.Connection
模块的x509客户端身份验证示例吗?我们需要做两件事(对于我的测试环境,有三件事)
defaultParamClient
设置空密码套件(我不知道为什么)证书存储
处理mkMyTLSSettings
将替换defaultParamsClient
结果中提到的部分。在用作onCertificateRequest
的函数中,您可以使用参数并根据参数发出不同的凭据。所需的值本身被读入
main
以摆脱IO
对于下面的程序,我修改了我在这里找到的位
{-#语言重载字符串}
模块主要在哪里
导入Data.Default.Class
导入网络.AMQP
导入Network.Socket.Internal(端口号)
导入网络.TLS
导入Network.TLS.Extra.Cipher(ciphersuite\u默认值)
导入数据.X509.CertificateStore(CertificateStore(..),readCertificateStore)
导入数据,也许吧
将符合条件的数据.ByteString作为BS导入
导入合格的网络。连接为C
将限定数据.ByteString.Lazy.Char8作为BL导入
mkMyTLSSettings::CertificateStore->Credential->C.TLSSettings
mkMyTLSSettings castore creds=
让defaultParams=defaultParamsClient“127.0.0.1”BS.empty
newClientShared=(clientShared默认参数){sharedCAStore=castore}
newClientSupported=(clientSupported defaultParams){supportedCiphers=ciphersuite_default}
newClientHooks=(clientHooks defaultParams){onCertificateRequest=\\\ uUx->return(Just creds)}
在C.TLSSettings$defaultParams{clientShared=newClientShared中
,clientSupported=newClientSupported
,clientHooks=newClientHooks
}
myTLSSettings::CertificateStore->Credential->TLSSettings
MytLSettings castore creds=TLSCustom$mkMytLSettings castore creds
MyTLS连接选项::TLS设置->连接选项
myTLSConnectionOpts opts=连接点
[((“127.0.0.1”,5671::端口号)]
"/"
[简单的“来宾”或“来宾”]
(仅131072)
没有什么
(仅1)
(只是选择)
testConnectionOpts::ConnectionOpts->IO()
testConnectionOpts opts=do
conn所以您想验证客户端,以便服务器可以信任客户端?很抱歉延迟回复。这是正确的。我会在今天下午的某个时候测试你的答案,然后告诉你答案的进展。谢谢如果你在工作中遇到问题,请告诉我。我们也可以就此开始聊天。非常感谢你的提议。昨天下午我有点时间,但不够。然后今天被耽搁了。所以这是明天早上的重点。我的计划是尝试更多地将您的答案纳入我的工作中,但如果失败,我将单独运行您的答案,并将结果发布回这里。再次感谢你的帮助。嘿,我还没有完全找到自己的解决方案;但我想你的回答让我触手可及。谢谢。希望你不介意我稍后带着更多的问题回来。(尽管我希望不会)。再次感谢,祝你周末愉快。
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Default.Class
import Network.AMQP
import Network.Socket.Internal (PortNumber)
import Network.TLS
import Network.TLS.Extra.Cipher (ciphersuite_default)
import Data.X509.CertificateStore (CertificateStore (..), readCertificateStore)
import Data.Maybe
import qualified Data.ByteString as BS
import qualified Network.Connection as C
import qualified Data.ByteString.Lazy.Char8 as BL
mkMyTLSSettings :: CertificateStore -> Credential -> C.TLSSettings
mkMyTLSSettings castore creds =
let defaultParams = defaultParamsClient "127.0.0.1" BS.empty
newClientShared = (clientShared defaultParams) { sharedCAStore = castore }
newClientSupported = (clientSupported defaultParams) { supportedCiphers = ciphersuite_default }
newClientHooks = (clientHooks defaultParams) { onCertificateRequest = \_ -> return (Just creds) }
in C.TLSSettings $ defaultParams { clientShared = newClientShared
, clientSupported = newClientSupported
, clientHooks = newClientHooks
}
myTLSSettings :: CertificateStore -> Credential -> TLSSettings
myTLSSettings castore creds = TLSCustom $ mkMyTLSSettings castore creds
myTLSConnectionOpts :: TLSSettings -> ConnectionOpts
myTLSConnectionOpts opts = ConnectionOpts
[("127.0.0.1", 5671 :: PortNumber)]
"/"
[plain "guest" "guest"]
(Just 131072)
Nothing
(Just 1)
(Just opts)
testConnectionOpts :: ConnectionOpts -> IO ()
testConnectionOpts opts = do
conn <- openConnection'' opts
chan <- openChannel conn
declareQueue chan newQueue {queueName = "hello"}
putStrLn "Trying to register callback"
consumeMsgs chan "hello" Ack myCallback
publishMsg chan "" "hello" newMsg {msgBody = (BL.pack "hello world"), msgDeliveryMode = Just Persistent}
getLine
closeConnection conn
putStrLn "connection closed"
main :: IO ()
main = do
testConnectionOpts defaultConnectionOpts
putStrLn "trying with tls"
castore <- maybe (error "couldn't read CA root Certificate") id <$> (readCertificateStore "/pathto/rootCA.pem")
creds <- either error id <$> credentialLoadX509 "/pathto/client.pem" "/pathto/client.key"
let opts = myTLSSettings castore creds
testConnectionOpts (myTLSConnectionOpts opts)
myCallback :: (Message, Envelope) -> IO ()
myCallback (msg, env) = do
putStrLn $ "received message: " ++ (BL.unpack $ msgBody msg)
ackEnv env