Поддерживаются ли клиентские сертификаты в 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

Я немного почитал и обнаружил, что клиентские сертификаты еще не поддерживаются в службе urfetch. Это все еще так? Если да, то есть ли обходной путь?


person user1734726    schedule 05.02.2013    source источник
comment
Спасибо, Инго, я рассмотрю эту функцию поддержки исходящих сокетов. Жаль, что клиентские сертификаты не поддерживаются.   -  person user1734726    schedule 06.02.2013
comment
Инго, я хотел бы проголосовать за ваш комментарий, но я довольно новичок в том, чтобы задавать вопросы о stackoverflow, поэтому, пожалуйста, скажите мне, как это сделать, проголосовав за ваш комментарий (не должны ли мы голосовать за ответы вместо комментариев? )   -  person user1734726    schedule 07.02.2013
comment
Ты прав. Я удалил комментарий и добавил его как ответ :)   -  person Ingo    schedule 07.02.2013


Ответы (3)


Сертификаты на стороне клиента в настоящее время не поддерживаются GAE. Вы можете использовать службу URLFetch через HTTPS. Но вы не можете использовать клиентские сертификаты. Вам следует попробовать функцию поддержки исходящих сокетов, который в настоящее время доступен в программе доверенных тестировщиков. Это может быть белый список функций, которые вы ищете. Я задавал аналогичный вопрос для GAE/J раньше.

Если вам это действительно нужно, используйте функцию исходящего сокета или запустите прокси-сервер в EC2.

person Ingo    schedule 06.02.2013
comment
Это уже не так - см. мой ответ ниже. - person BooTooMany; 20.03.2018

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)
person BooTooMany    schedule 20.03.2018
comment
Как можно было бы создать HTTPS-запрос с ssl.wrap_socket, как упоминается в вопросе? Потребует ли это реализации большого количества низкоуровневой логики связи HTTP, или может requests или другая библиотека использовать это как-то ? - person David Pärsson; 04.08.2019

Чтобы расширить ответ BooTooMany, теперь можно сделать это с помощью отличного requestsбиблиотека, если базовый код использует сокеты. Выполните следующие действия, чтобы использовать его:

  1. Сокеты доступны только для платных приложений. Убедитесь, что в вашем приложении включена оплата.
  2. Установите requests в каталог lib/. В настоящее время я использую v2.21.0. Удостоверьтесь, что не исправите requests для использования адаптеров AppEngine, предоставленных requests-toolbelt, несмотря на то, что это рекомендовано документы. Это заставляет requests использовать urlfetch вместо сокетов, которые доступны для бесплатных приложений, но в настоящее время не поддерживают сертификаты на стороне клиента.
  3. В вашем app.yaml включите библиотеку SSL:
libraries:
- name: ssl
  version: latest
  1. В вашем 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)
person David Pärsson    schedule 05.08.2019