Поддерживаются ли сертификаты на стороне клиента в App Engine
Я занимаюсь разработкой приложения для движка приложений Google, и мне нужно подключиться к веб-сервису с помощью 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. Это все еще так? Если так, есть ли обходной путь?
2 ответа
Сертификаты на стороне клиента в настоящее время не поддерживаются GAE. Вы можете использовать сервис URLFetch через HTTPS. Но вы не можете использовать клиентские сертификаты. Вам следует попробовать функцию поддержки исходящих сокетов, которая в настоящее время доступна в программе доверенного тестера. Это может внести в белый список функциональность, которую вы ищете. Я задавал подобный вопрос для GAE/J раньше.
Если вам это действительно нужно, либо воспользуйтесь функцией исходящего сокета, либо запустите прокси-сервер в EC2.
Чтобы расширить ответ BooTooMany, теперь это можно сделать с помощью отличного requests
библиотека, если базовый код использует сокеты. Выполните следующие действия, чтобы использовать его:
- Сокеты доступны только для платных приложений. Убедитесь, что в вашем приложении включен биллинг.
- Установить
requests
в вашlib/
каталог. Сейчас я использую v2.21.0. Убедитесь, что не обезьянаrequests
использовать адаптеры AppEngine, предоставленныеrequests-toolbelt
, несмотря на то, что это рекомендовано документами. Это делаетrequests
использоватьurlfetch
вместо сокетов, что доступно для бесплатных приложений, но в настоящее время не поддерживает сертификаты на стороне клиента. - В вашем
app.yaml
, включите библиотеку SSL:
libraries:
- name: ssl
version: latest
- В вашем
app.yaml
, включите сокеты для сервера разработки:
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)
Python SSL теперь поддерживается в GAE - см. 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)