App Engine 支持客户端证书吗
我正在开发一个谷歌应用引擎的应用程序,需要通过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。按照以下步骤来使用它:
- 首先,sockets 仅对付费应用可用。确保你的应用已经启用了计费功能。
- 在你的
lib/
目录中安装requests
。我现在使用的是版本2.21.0。要注意不要将requests
修改为使用requests-toolbelt
提供的 AppEngine 适配器,尽管文档中推荐这样做。这会让requests
使用urlfetch
,而不是 sockets,虽然urlfetch
对于免费应用可用,但目前不支持客户端证书。 - 在你的
app.yaml
文件中,启用 SSL 库:
libraries:
- name: ssl
version: latest
- 在你的
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上运行一个代理。