App Engine 支持客户端证书吗

4 投票
3 回答
1564 浏览
提问于 2025-04-17 14:49

我正在开发一个谷歌应用引擎的应用程序,需要通过SOAP连接到一个网络服务。我使用的是pysimplesoap这个库(已经用一些代码进行了修补,具体可以在这里找到),来解析XML,并使用客户端证书发送请求。

在我本地环境中进行简单的单元测试时,这一切都能正常工作,我能从网络服务那里得到正确的响应。

但是,当我在应用引擎中运行完全相同的代码时,却出现了这个:

  File "/Users/me/Documents/workspace/blixem/model/communicate/communication_channel.py", line 60, in generate_soap_message_pysimplesoap
    response = client.SendDocument('LA.XML', 'TESTCASE', 'data')
  File "/Users/me/Documents/workspace/blixem/lib/pysimplesoap/client.py", line 152, in <lambda>
    return lambda *args, **kwargs: self.wsdl_call(attr,*args,**kwargs)
  File "/Users/me/Documents/workspace/blixem/lib/pysimplesoap/client.py", line 320, in wsdl_call
    response = self.call(method, *params)
  File "/Users/me/Documents/workspace/blixem/lib/pysimplesoap/client.py", line 215, in call
    self.xml_response = self.send(method, self.xml_request)
  File "/Users/me/Documents/workspace/blixem/lib/pysimplesoap/client.py", line 241, in send
    location,"POST", body=xml, headers=headers )
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/httplib2/httplib2/__init__.py", line 1457, in request
    self.disable_ssl_certificate_validation)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/httplib2/httplib2/__init__.py", line 1143, in __init__
    strict, timeout, proxy_info, ca_certs, disable_ssl_certificate_validation)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/httplib2/httplib2/__init__.py", line 1092, in __init__
    raise NotSupportedOnThisPlatform()
NotSupportedOnThisPlatform

我查了一些资料,发现客户端证书在urlfetch服务中似乎还不被支持。这种情况现在还是这样吗?如果是的话,有没有什么解决办法?

3 个回答

0

现在在Google App Engine(GAE)上支持Python的SSL功能了 - 你可以查看这个链接了解更多信息:https://cloud.google.com/appengine/docs/standard/python/sockets/ssl_support

这意味着你现在可以使用客户端证书了。具体的内容可以在那个网页上找到:

 # Example of a dynamic key and cert.
  datastore_record_k = ndb.Key('Employee', 'asalieri', 'Address', 1)
  datastore_record = datastore_record_k.get()
  key_str = datastore_record.key_str
  cert_str = datastore_record.cert
  ssl_server = ssl.wrap_socket(server_sock,
                              server_side=False,
                              keyfile=StringIO.StringIO(key_str),
                              certfile=StringIO.StringIO(cert_str),
                              cert_reqs=ssl.CERT_REQUIRED,
                              ssl_version=ssl.PROTOCOL_SSLv23,
                              ca_certs=CERTIFICATE_FILE)
1

为了更详细地说明 BooTooMany的回答,现在可以使用非常棒的 requests,只要底层代码使用的是 sockets。按照以下步骤来使用它:

  1. 首先,sockets 仅对付费应用可用。确保你的应用已经启用了计费功能。
  2. 在你的 lib/ 目录中安装 requests。我现在使用的是版本2.21.0。要注意不要requests 修改为使用 requests-toolbelt 提供的 AppEngine 适配器,尽管文档中推荐这样做。这会让 requests 使用 urlfetch,而不是 sockets,虽然 urlfetch 对于免费应用可用,但目前不支持客户端证书。
  3. 在你的 app.yaml 文件中,启用 SSL 库:
libraries:
- name: ssl
  version: latest
  1. 在你的 app.yaml 文件中,为开发服务器启用 sockets:
env_variables:
  GAE_USE_SOCKETS_HTTPLIB: 'yes'

现在你可以使用客户端证书进行请求了:

import requests

def make_request(url):
    cert = ('cert_file.pem', 'key_file.pem')
    server_cert_file = 'server_cert_file.pem'
    return requests.get(url=url, cert=cert, verify=server_cert_file)
2

目前,GAE(Google App Engine)不支持客户端证书。你可以通过HTTPS使用URLFetch服务,但不能使用客户端证书。你可以尝试一下出站套接字支持功能,这个功能现在在受信测试者计划中可以使用。这个功能可能会满足你的需求。我之前也问过关于GAE/J的类似问题

如果你真的需要这个功能,可以选择使用出站套接字功能,或者在EC2上运行一个代理。

撰写回答