使用 Google API 的域范围委派时出现未经授权的客户端错误
Unauthorized client error when using domain wide delegation with Google API
我们正在使用 Google API Ruby 具有域范围委派的客户端来更新用户的联系人,解析电子邮件以将它们与我们的数据库配对等。4 月 1 日之前一切正常很好,但是,从那时起我们得到 unauthorized_client
错误响应。
Signet::AuthorizationError (Authorization failed. Server message:)
{
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
}
我已经尝试了什么?
我已尝试将 google-api-ruby-client
和 googleauth
宝石更新到最新版本。没有任何变化。
我还尝试(两次)生成新的服务帐户,为 DWD 启用它,并使用服务帐户的客户端 ID 在 G Suite 管理控制台中添加所需的范围。我在管理控制台中添加范围后等待了 24 小时,但没有任何变化。
请注意,过去使用相同的设置一切正常。
最少的测试代码
这是引发错误的最少代码。
require 'googleauth'
require 'google/apis/gmail_v1'
creds = ENV['GOOGLE_SERVICE_ACCOUNT'] # JSON downloaded from cloud console
# is saved in this ENV variable
creds_json = JSON.parse(creds)
creds_json_io = StringIO.new(creds_json.to_json)
auth = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: creds_json_io,
scope: [Google::Apis::GmailV1::AUTH_GMAIL_MODIFY]
)
auth.sub = 'admin@slideslive.com' # without this line everything works fine
# and I get the access token
auth.fetch_access_token
据我所知,我们正在根据可用文档进行所有操作。请问大家有什么建议吗?
更新
我也试过在同一组织下创建一个新的 Google 云平台项目,只添加了服务帐户,但一切都保持不变。
所以我终于弄清楚问题出在哪里了。
在其他范围中,我还启用了这些:
http://www.google.com/m8/feeds/contacts/
http://www.google.com/m8/feeds/groups/
原来 Google 可能使它们无效,它们现在需要 https
而不是 http
。
如果他们提供更好的错误消息就好了,比如在 Google 管理控制台中授权时输入的范围无效。
我在尝试为与我用于服务帐户的相同范围授权普通 OAuth2 客户端 ID 时发现错误。 OAuth2 同意屏幕显示正确的错误消息。
更新
这是我为排除服务帐户错误而创建的清单:
- 检查是否在 Google Cloud Console 中为服务帐户启用了域范围委派。
- 检查您是否在 Google 管理控制台中使用服务帐户的客户端 ID(不是其电子邮件!)输入了 正确的 范围。确保所有范围都有效!他们可能在有生之年变得无效。当您输入无效范围时,即使在有效范围内获取访问令牌时也会出现
unauthorized_client
错误。
我们正在使用 Google API Ruby 具有域范围委派的客户端来更新用户的联系人,解析电子邮件以将它们与我们的数据库配对等。4 月 1 日之前一切正常很好,但是,从那时起我们得到 unauthorized_client
错误响应。
Signet::AuthorizationError (Authorization failed. Server message:)
{
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
}
我已经尝试了什么?
我已尝试将 google-api-ruby-client
和 googleauth
宝石更新到最新版本。没有任何变化。
我还尝试(两次)生成新的服务帐户,为 DWD 启用它,并使用服务帐户的客户端 ID 在 G Suite 管理控制台中添加所需的范围。我在管理控制台中添加范围后等待了 24 小时,但没有任何变化。
请注意,过去使用相同的设置一切正常。
最少的测试代码
这是引发错误的最少代码。
require 'googleauth'
require 'google/apis/gmail_v1'
creds = ENV['GOOGLE_SERVICE_ACCOUNT'] # JSON downloaded from cloud console
# is saved in this ENV variable
creds_json = JSON.parse(creds)
creds_json_io = StringIO.new(creds_json.to_json)
auth = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: creds_json_io,
scope: [Google::Apis::GmailV1::AUTH_GMAIL_MODIFY]
)
auth.sub = 'admin@slideslive.com' # without this line everything works fine
# and I get the access token
auth.fetch_access_token
据我所知,我们正在根据可用文档进行所有操作。请问大家有什么建议吗?
更新
我也试过在同一组织下创建一个新的 Google 云平台项目,只添加了服务帐户,但一切都保持不变。
所以我终于弄清楚问题出在哪里了。 在其他范围中,我还启用了这些:
http://www.google.com/m8/feeds/contacts/
http://www.google.com/m8/feeds/groups/
原来 Google 可能使它们无效,它们现在需要 https
而不是 http
。
如果他们提供更好的错误消息就好了,比如在 Google 管理控制台中授权时输入的范围无效。
我在尝试为与我用于服务帐户的相同范围授权普通 OAuth2 客户端 ID 时发现错误。 OAuth2 同意屏幕显示正确的错误消息。
更新
这是我为排除服务帐户错误而创建的清单:
- 检查是否在 Google Cloud Console 中为服务帐户启用了域范围委派。
- 检查您是否在 Google 管理控制台中使用服务帐户的客户端 ID(不是其电子邮件!)输入了 正确的 范围。确保所有范围都有效!他们可能在有生之年变得无效。当您输入无效范围时,即使在有效范围内获取访问令牌时也会出现
unauthorized_client
错误。