Twisted Python TLS 服务器:将客户端证书信息传递给资源/端点
Twisted Python TLS server : pass client certificate info to resource / endpoint
我正在尝试在 Twisted python 中实现带有 TLS 客户端证书的 XML-RPC 服务器。
此外,最终目标是只允许定义的用户列表(即证书列表)访问某些方法。
虽然我完成了第一部分,但我很难将证书信息传输到我计划应用过滤器的 XMLRPC.render_POST
。
我找到了 描述如何显示通用名称,但我仍然有两个问题:
- 来自客户端的XML-RPC调用在收到应答后没有return,我猜这意味着请求没有正确完成
- 我不知道如何将此信息进一步向下传递到 XMLRPC 资源
这是我目前的情况:
import sys
import OpenSSL
from twisted.python.filepath import FilePath
from twisted.internet import endpoints
from twisted.internet import ssl
from twisted.python import log
from twisted.web import xmlrpc, server
from twisted.internet.ssl import Certificate
from twisted.internet.protocol import Protocol
class ReportWhichClient(Protocol):
# adapted from
def dataReceived(self, data):
peerCertificate = Certificate.peerFromTransport(self.transport)
print(peerCertificate.getSubject().commonName.decode('utf-8'))
class Example(xmlrpc.XMLRPC):
"""
An example object to be published.
"""
def xmlrpc_echo(self, x):
"""
Return all passed args.
"""
return x
def main():
log.startLogging(sys.stdout)
from twisted.internet import reactor
key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,FilePath("my.key").getContent())
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,FilePath("my.crt").getContent())
ca = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, FilePath("ca.crt").getContent())
contextFactory = ssl.CertificateOptions(privateKey=key, certificate=cert, verify=True, caCerts=[ca] , requireCertificate=True)
root = Example()
endpoint = endpoints.SSL4ServerEndpoint(reactor, 8083,contextFactory)
mySite = server.Site(root)
mySite.protocol = ReportWhichClient
endpoint.listen(mySite)
reactor.run()
if __name__ == '__main__':
main()
这是正确的做法吗?我应该怎么做才能在资源级别获得所需的信息?
任何答案都很好,此时我已经绞尽脑汁尝试了很多解决方案,但没有任何结果。
谢谢
好吧,解决方案一直摆在我面前。
重新阅读源代码后,似乎 transport
出现在请求中。我所要做的就是添加 @withRequest
装饰器并从那里获取所有信息:
class Example(xmlrpc.XMLRPC):
@withRequest
def xmlrpc_echo(self, request, x):
peerCertificate = Certificate.peerFromTransport(request.transport)
key = peerCertificate.getPublicKey().original
# display the client public key in PEM format
print(OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, key))
return x
我正在尝试在 Twisted python 中实现带有 TLS 客户端证书的 XML-RPC 服务器。 此外,最终目标是只允许定义的用户列表(即证书列表)访问某些方法。
虽然我完成了第一部分,但我很难将证书信息传输到我计划应用过滤器的 XMLRPC.render_POST
。
我找到了
- 来自客户端的XML-RPC调用在收到应答后没有return,我猜这意味着请求没有正确完成
- 我不知道如何将此信息进一步向下传递到 XMLRPC 资源
这是我目前的情况:
import sys
import OpenSSL
from twisted.python.filepath import FilePath
from twisted.internet import endpoints
from twisted.internet import ssl
from twisted.python import log
from twisted.web import xmlrpc, server
from twisted.internet.ssl import Certificate
from twisted.internet.protocol import Protocol
class ReportWhichClient(Protocol):
# adapted from
def dataReceived(self, data):
peerCertificate = Certificate.peerFromTransport(self.transport)
print(peerCertificate.getSubject().commonName.decode('utf-8'))
class Example(xmlrpc.XMLRPC):
"""
An example object to be published.
"""
def xmlrpc_echo(self, x):
"""
Return all passed args.
"""
return x
def main():
log.startLogging(sys.stdout)
from twisted.internet import reactor
key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,FilePath("my.key").getContent())
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,FilePath("my.crt").getContent())
ca = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, FilePath("ca.crt").getContent())
contextFactory = ssl.CertificateOptions(privateKey=key, certificate=cert, verify=True, caCerts=[ca] , requireCertificate=True)
root = Example()
endpoint = endpoints.SSL4ServerEndpoint(reactor, 8083,contextFactory)
mySite = server.Site(root)
mySite.protocol = ReportWhichClient
endpoint.listen(mySite)
reactor.run()
if __name__ == '__main__':
main()
这是正确的做法吗?我应该怎么做才能在资源级别获得所需的信息?
任何答案都很好,此时我已经绞尽脑汁尝试了很多解决方案,但没有任何结果。
谢谢
好吧,解决方案一直摆在我面前。
重新阅读源代码后,似乎 transport
出现在请求中。我所要做的就是添加 @withRequest
装饰器并从那里获取所有信息:
class Example(xmlrpc.XMLRPC):
@withRequest
def xmlrpc_echo(self, request, x):
peerCertificate = Certificate.peerFromTransport(request.transport)
key = peerCertificate.getPublicKey().original
# display the client public key in PEM format
print(OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, key))
return x