无法从本地App Engine开发服务器访问BigQuery

时间:2013-12-03 10:55:56

标签: google-app-engine google-oauth google-bigquery google-api-python-client

这是一个与python Google AppEngine应用程序和Google的BigQuery之间的服务器到服务器授权有关的问题,但可能与其他云服务相关。

tldr;是否可以让App Engine本地开发服务器使用远程BigQuery服务进行身份验证?更好的是有一个本地BigQuery吗?

我知道AppAssertionCredentials当前不能在本地开发服务器上运行,尽管这本身就非常令人沮丧。

用于标准python代码的替代方法,在本地开发服务器沙箱之外,详细here对本地开发服务器不起作用,因为即使启用了PyCrypto,沙箱也不允许某些posix模块,例如'命令pwd'。

我有 AppAssertionCredentials 在远程服务器上工作,而 SignedJwtAssertionCredentials 方法在本地python中工作,因此服务帐户设置正确。

导入在try / except块中的oauth2client / crypt.py内失败 - 在将它们注释掉后,很容易看到沙箱白名单异常。

我已经摆弄了将'pwd'添加到白名单中,然后又出现了另一个问题,所以我匆匆走出那个兔子洞。

我已经尝试将PyCrypto直接包含在项目中,但结果相似。

我也尝试过使用类似结果的OpenSSL。

我找了一个当地的appengine特定的PyCrypto无济于事,我错过了吗?我应该说这是在Mac OSX上 - 也许我应该启动一个linux盒子然后放弃它?

5 个答案:

答案 0 :(得分:38)

最近发布的Google App Engine SDK在开发服务器上添加了对AppAssertionCredentials方法的支持。要在本地使用此方法,请将以下参数添加到dev_appserver.py

$ dev_appserver.py --help
...
Application Identity:
  --appidentity_email_address APPIDENTITY_EMAIL_ADDRESS
                        email address associated with a service account that
                        has a downloadable key. May be None for no local
                        application identity. (default: None)
  --appidentity_private_key_path APPIDENTITY_PRIVATE_KEY_PATH
                        path to private key file associated with service
                        account (.pem format). Must be set if
                        appidentity_email_address is set. (default: None)

使用这些:

  1. Google Developer Console中,选择一个项目,然后导航到" API& AUTH" - > "证书" - > "创建新的客户ID"。

  2. 选择"服务帐户"并按照提示下载PKCS12(.p12)格式的私钥。记下服务帐户的电子邮件地址。

  3. 确保将该服务帐户电子邮件地址添加到"权限"包含需要访问的数据的任何项目的选项卡,默认情况下会添加到创建它的项目团队中。

  4. 使用以下命令将PKCS12格式转换为PKCS1格式:

    $ cat /path/to/xxxx-privatekey.p12 | openssl pkcs12 -nodes -nocerts -passin pass:notasecret | openssl rsa > /path/to/secret.pem

  5. 以<{1}}开头:

    dev_appserver.py

  6. 在本地使用$ dev_appserver.py --appidentity_email_address xxxx@developer.gserviceaccount.com --appidentity_private_key_path /path/to/secret.pem ...模块和appidentity的方式与通常在制作时相同。

  7. 请确保AppAssertionCredentials位于您的应用程序源目录之外,以免意外将其部署为您的应用程序的一部分。

答案 1 :(得分:3)

因此,更深入地搜索PyCrypto和本地appengine沙箱引导我进入这个线程并特别回应......

https://code.google.com/p/googleappengine/issues/detail?id=1627#c22

  

这在1.7.4中已修复。但是,您必须使用easy_install -Z   (--always-unzip)安装PyCrypto。中的默认zipfile选项   OSX 10.8与中的沙盒模拟不兼容   dev_appserver。

解决方案结果非常直接......

我用过:

sudo easy_install pycrypto

应该是:

sudo easy_install -Z pycrypto

按照上面的帖子。使用PIP也可以使用:

pip install pycrypto 

或手动下载和安装pycrypto也可以。我测试了这三个。

如果您已经安装了带有easy_install且没有-Z标志的pycrypto,那么您可能需要安装pip,以便您可以轻松卸载pycrypto ......

easy_install pip

我建立并安装了libgmp的记录,因为pil和手动安装显示了这个警告...

  

警告:未找到GMP或MPIR库;没有建设   Crypto.PublicKey._fastmath。

虽然这给了我fastmath,但解决问题并不是必不可少的,因为Crypto libs优雅地无法减速。

另一个让我失望的地方是我从app.yaml中删除了pycrypto,同时测试OpenSSL是否可能给我所需要的一切。

所以别忘了添加......

- name: pycrypto
  version: latest

libraries:部分下的app.yaml。

由于缺少原始的_counter库,因此没有导入,因此Counter失败等。

此外,对于记录,任何关于必须将Crypto移动到应用程序文件夹本身或者从/Library/Python/2.7/site-packages/Crypto的默认Mac OS X位置的说法仅在早期版本的开发中有效服务器

同样,现在没有必要编辑任何_WHITE_LIST_C_MODULES列表(在appengine 1.8之后的sandbox.py中,其中还包括允许Crypto.Util._counter等的正则表达式)

如果你在发现密钥问题之前到达这里的另一个难题是从控制台下载的密钥文件是PKCS12并以十六进制文本形式下载,所以我将其转换为二进制文件,然后将其转换为PEM所以我可以将它包含在源代码中。

答案 2 :(得分:2)

我在这一天挣扎了一两天。我终于能够让localhost使用服务器到服务器身份验证,服务帐户和.p12证书。

如果它对任何人都有帮助,这里有一个简单的要点:https://gist.github.com/dandelauro/7836962

答案 3 :(得分:0)

  

是否可以让App Engine本地开发服务器使用远程BigQuery服务进行身份验证?

我认为目前在BigQuery服务和本地App Engine服务器之间使用AppAssertionCredentials作为身份验证方法是不可能的。

或者,我正在使用与特定用户关联的OAuth2身份验证(此用户必须在google api console的项目中注册)才能从本地App Engine服务器访问BigQuery。

为了获得用户OAuth2身份验证,我在应用代码中使用了oauth2client.client模块。

我希望这会对你的问题有所帮助。

<强>更新

这就是我为获取用户OAuth2授权所做的工作。

<强>编辑:

添加了缺少的导入语句。 谢谢mattes!

import os
import webapp2
import httplib2
from oauth2client.client import OAuth2Credentials
from oauth2client.appengine import StorageByKeyName, CredentialsModel, OAuth2DecoratorFromClientSecrets
from google.appengine.api import users

oauth2_decorator = OAuth2DecoratorFromClientSecrets(
    os.path.join(os.path.dirname(__file__), 'client_secrets.json'),
    scope='https://www.googleapis.com/auth/bigquery')
oauth2_decorator._kwargs = {'approval_prompt': 'force'}


class TestPage(webapp2.RequestHandler):
  @oauth2_decorator.oauth_required
  def get(self):
    user_id = users.get_current_user().user_id()
    credentials = StorageByKeyName(CredentialsModel, user_id, 'credentials').locked_get()
    http = credentials.authorize(httplib2.Http()) # now you can use this http object to access BigQuery service


application = webapp2.WSGIApplication([
  ('/', TestPage),
  (oauth2_decorator.callback_path, oauth2_decorator.callback_handler()),
], debug=True)

答案 4 :(得分:0)

我同意第一篇文章 - 本地主机/生产阻抗是a **的真正痛苦。 AppAssertionCredentials是继续生产的正确方法,我不想在生产和localhost之间有两个不同的代码路径。因此,需要调整开发环境,以便能够执行所需的身份验证,而不会影响主代码路径。

例如,也许开发人员可以使用appcfg.py使用他们自己的Google帐户登录,然后该身份验证将被缓存一段时间,以便AppAssertionCredentials可以解决。可以在开发人员的Google帐户中为相应的环境授予权限(例如,开发和测试)

re:“本地BigQuery” - 我们有一些初始的东西,使用SQLLite来模拟BigQuery交互以进行单元测试和其他离线/本地测试,但当然,这不是一个很好的模拟。我同意所有Cloud Platform产品都需要花费尽可能多的时间来考虑App Engine的开发时间体验。