【问题标题】:Is it possible to use "Domain-wide Delegation of Authority" with gdata-python-client?是否可以在 gdata-python-client 中使用“域范围的授权”?
【发布时间】:2013-12-19 08:16:20
【问题描述】:

我正在使用gdata-python-client 访问Google Domain Shared Contacts API

在企业应用程序中,您可能希望在没有任何手动授权的情况下以编程方式访问用户数据。

有一个称为 2LO(2 腿 OAuth)的协议,但似乎它与已弃用的 OAuth1 相关联:“重要提示:OAuth 1.0 已弃用,新 OAuth 1.0 客户端的注册已关闭。”遍布Oauth1 docs

Domain-wide Delegation of Authority”有一个基于 OAuth2 的新配方:

在 Google Apps 域中,域管理员可以向第三方应用程序授予域范围内访问其用户数据的权限 — 这称为域范围内的授权。要以这种方式委派权限,域管理员可以使用具有 OAuth 2.0 的服务帐户。

这适用于google-api-python-client,但不适用于gdata-python-client

问题:有没有办法用 Python 实现这一点?似乎来自 gdata 客户端的代码是史前的 - 是否有任何其他 GAE 运行时具有支持数据 API 委托的现代客户端库?

[更新]

如果我签署一个 httplib2 连接并调用 Atom 端点,我就能够检索提要。

http = httplib2.Http()
http = credentials.authorize(http)
resp, content = http.request(
    'https://www.google.com/m8/feeds/contacts/default/full', 'GET'
)

不幸的是 gdata-python-client 使用 httplib 而不是 httplib2。

[已解决]

也许我错过了一些步骤,但看起来令牌在我们使用 httplib2 执行调用之前无效。在运行 [aeijdenberg] 的答案中给出的示例之前,我必须运行上述代码,否则我会得到 401。

【问题讨论】:

  • 您简要地提到了 GAE - 这是否打算部署在 Google App Engine 上?如果是这样 - 您需要做一些额外的工作才能让 SignedJwtAssertionCredentials 正常运行。如果需要,请告诉我,我会深入了解如何做到这一点。
  • 是的,它应该在 GAE 上托管。
  • 我已修改答案以包含 GAE 的步骤。

标签: python google-oauth


【解决方案1】:

这是一个如何在 Python 中使用 gdata 库在 Google App Engine 中进行域范围委派的示例:

  1. 创建一个项目 (https://cloud.google.com/console#/project)。

  2. 在“APIs & Auth”下启用您需要使用的 API(有些 gdata API 没有出现在此处,如果有,请跳过此步骤)。

  3. 在“APIs & Auth” -> “Credentials”下创建一个服务帐户类型的新 OAuth2 客户端 ID。记下电子邮件地址和客户端 ID,并将下载的私钥保存到安全位置。

  4. 作为域管理员转到管理控制台 (https://admin.google.com/AdminHome),导航到“安全”->“高级设置”->“托管的第三方 OAuth 客户端访问”。

  5. 将之前的完整客户端 ID 粘贴到“客户端名称”字段中,然后将 API 访问所需的范围粘贴到范围字段中。

  6. 由于我们在 Google App Engine 上运行,我们需要将 PKCS12 格式的私钥转换为 PEM 格式(因为目前部署在 Google App Engine 上的 PyCrypto 库不支持 PCKS12):

    cat secret-privatekey.p12 | openssl pkcs12 -nodes -nocerts -passin pass:notasecret | openssl rsa > secret-privatekey.pem
    
  7. 把这个文件放到你的app目录下。

  8. https://code.google.com/p/google-api-python-client/downloads/list下载Google API Python客户端,选择google-api-python-client-gae-1.2.zip

  9. 解压到你的应用目录中:

    unzip ~/Downloads/google-api-python-client-gae-1.2.zip
    
  10. https://code.google.com/p/gdata-python-client/downloads/list下载gdata python客户端,选择gdata-2.0.18.zip

  11. 在你的应用目录中安装这个:

    unzip ~/Downloads/gdata-2.0.18.zip
    mv gdata-2.0.18/src/* .
    rm -rf gdata-2.0.18/
    
  12. 确保 PyCrypto 已安装在本地(但不在您的应用程序目录中):

    sudo easy_install pycrypto
    
  13. 在您的 app.yaml 中,将 PyCrypto 添加为库:

    libraries:
    - name: pycrypto
      version: "2.6"
    
  14. 声明以下帮助类:

    import httplib2
    
    class TokenFromOAuth2Creds:
      def __init__(self, creds):
        self.creds = creds
      def modify_request(self, req):
        if self.creds.access_token_expired or not self.creds.access_token:
          self.creds.refresh(httplib2.Http())
        self.creds.apply(req.headers)
    
  15. 使用私钥创建SignedJwtAssertionCredentials对象:

    from oauth2client.client import SignedJwtAssertionCredentials
    
    credentials = SignedJwtAssertionCredentials(
      "<service account email>@developer.gserviceaccount.com",
      file("secret-privatekey.pem", "rb").read(),
      scope=["http://www.google.com/m8/feeds/"],
      prn="<user to impersonate>@your-domain.com"
    )
    
  16. 创建一个 gdata 客户端并使用它:

    gd_client = gdata.contacts.client.ContactsClient('your-domain.com')
    gd_client.auth_token = TokenFromOAuth2Creds(credentials)
    xxx = gd_client.get_contacts()
    

【讨论】:

  • 感谢您的支持。这给了我Token invalid - Invalid token: Cannot parse AuthSub token: None。我知道我已经很接近了,但是已经敲了几个小时的头,不知道如何解决这个问题。
  • 你能分享一下调用gdata库的代码sn-p吗?
  • 试过你的例子,同样的结果。将更新问题,再次感谢。
  • 哎呀...我的错...我不知道我做错了什么...它现在正在工作!!!非常感谢,我希望我能投票更多。
  • 好吧,我发现了:除非我在调用 gdata-python-client 方法之前使用 httplib2 进行调用,否则将无法正常工作。
猜你喜欢
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 2023-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多