2013-03-19 4 views
26

거의 사용되지 않지만 스냅의 클라이언트 인증서에 액세스 할 수 있습니까?Snap을 사용하여 클라이언트 인증서를 확인하는 방법

그렇지 않은 경우 다른 웹 스택을 사용할 수 있습니까?

+1

더 일반적으로 저는 Haskell 웹 프레임 워크가 인증서 기반 클라이언트 인증을 지원하는지 여부를 알고 싶습니다. –

+0

이것은 일종의 비 응답이지만 해결 방법으로 nginx를 사용하여 인증서를 확인하고 헤더를 통해 DN을 전달할 수 있습니다. –

답변

1

Snap의 snap-server 패키지에서는 사용할 수 없습니다.이 패키지는 서버를 어떻게 운영하는지 가정합니다.

Buuuuut 포크로 만들거나 별도의 모듈로 빌드하기가 어렵지 않습니다 (일부 내부 값을 내 보내지 않으므로 일부 코드를 복사해야합니다). bindHttps, located in Snap.Internal.Http.Server.TLS이 원하는 대상입니다. 이 함수는 대부분 HsOpenSSL 라이브러리의 OpenSSL.Session에 대한 호출을 감싸는 래퍼이며, 그 자체가 OpenSSL 라이브러리 주위의 느슨한 래퍼입니다.

우리에게 운 좋은 OpenSSL은 클라이언트 인증서를 완벽하게 지원합니다. verification modeSSL_VERIFY_PEER으로 설정하기 만하면됩니다. 당신도 할 수있는 다른 손잡이가 있습니다. 실제로 클라이언트 인증서를 확인하기 위해 인증서 체인을 설치해야합니다. 신뢰의 사슬과 모든 재즈. 참고로 nginx does it을 참조하십시오.

더 좋은 점은이 함수가 contextSetVerificationMode :: SSLContext -> VerificationMode -> IO()HsOpenSSLexposed 인 것입니다. 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입니다.