【问题标题】:Google Cloud Endpoints Metadata Server AuthenticationGoogle Cloud Endpoints 元数据服务器身份验证
【发布时间】:2018-09-23 12:06:29
【问题描述】:

上下文:

对于我正在处理的项目,我已按照说明here 使用位于可扩展服务代理 (ESP) 后面的 gRPC API 的服务帐户设置服务身份验证服务。作为参考,我的身份验证配置如下所示

authentication:
  providers:
    - id: google_service_account
      issuer: <service-account-email>
      jwks_uri: https://www.googleapis.com/robot/v1/metadata/x509/<service-account-email>
  rules:
    - selector: "*"
      requirements:
        - provider_id: google_service_account

然后我有一个 ruby​​ 客户端,它从磁盘读取服务帐户密钥(通过 GCP 控制台获得)并使用 googleauth gem 生成 JWT,用于通过 API 进行身份验证。

module Authenticated
  def credentials
    @credentials ||= Google::Auth::ServiceAccountJwtHeaderCredentials
      .make_creds(json_key_io: service_account_json_io)
      .apply(jwt_aud_uri: ENV.fetch('SERVICE_NAME'))
  end

  def self.service_account
    @service_account ||= StringIO.new(
      File.read('/etc/secrets/service-account.json'),
    )
  end

  private

  def service_account_json_io
    Authenticated.service_account.tap(&:rewind)
  end
end

目前处于工作状态,客户端可以通过 ESP 进行身份验证。

问题:

自从实现上述内容后,我有另一个客户端应用程序需要重用相同的 API。这意味着必须生成一个新的服务帐户密钥并将其安装到新的应用程序中以进行身份​​验证。最终,如果我创建更多客户端,那么必须安全地存储许多服务帐户密钥很容易出错并且存在潜在的安全风险。相反,我想使用 GCE 元数据服务器从假设默认计算引擎服务帐户(尽管我稍后可能使用不同的帐户)生成 JWT,并将其传递给 ESP。

到目前为止,我尝试的是更改 ESP 身份验证配置,如下所示

authentication:
  providers:
    - id: google_service_account
      issuer: https://accounts.google.com
      jwks_uri: https://www.googleapis.com/robot/v1/metadata/x509/<gce-default-service-account-email>
  rules:
    - selector: "*"
      requirements:
        - provider_id: google_service_account

并更新 ruby​​ 客户端以从元数据服务器请求 JWT,如下所示

module Authenticated
  METADATA_SERVER_IDENTITY_URI = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?format=full&audience='.freeze

  def credentials
    { authorization: "Bearer #{identity_jwt}" }
  end

  private

  def identity_jwt
    http = Net::HTTP.new(identity_uri.hostname)
    http.request(identity_request).body
  end

  def identity_request
    Net::HTTP::Get.new(identity_uri).tap do |req|
      req.add_field('Metadata-Flavor', 'Google')
    end
  end

  def identity_uri
    URI.parse("#{METADATA_SERVER_IDENTITY_URI}https://#{ENV['SERVICE_NAME']}")
  end
end

这会再次生成 JWT,但是这次将颁发者设置为 https://accounts.google.com(如 ESP 身份验证配置中所反映的那样)。但是,这一次客户端无法通过 ESP 报告 Error: KEY_RETRIEVAL_ERROR 进行身份验证

问题...最后:

是否可以使用通过 GCE 元数据服务器生成的 JWT 对 ESP 进行身份验证?以及配置步骤是什么?

【问题讨论】:

    标签: google-cloud-platform jwt google-cloud-endpoints grpc


    【解决方案1】:

    通过从 Google Cloud Endpoints 配置 yaml 中删除 jwks 键,它会强制 ESP 使用 OpenID 发现来获取将用于获取正确 JWKjwks_uri。这可以在api manager configuration 中看到。

    鉴于问题中定义的相同颁发者 (accounts.google.com),代码将生成一个指向 https://accounts.google.com/.well-known/openid-configuration 的 URL,其中包含 jwks_uri。 ESP 使用此处指定的jwks 来验证 JWT。

    【讨论】:

      【解决方案2】:

      是的,在第二种情况下,检索到的 JWT 是 Google 签名的(“iss”是 https://accounts.google.com)JWT,而不是服务帐户签名(“iss”是服务帐户电子邮件)JWT。所以 JWT URI 需要相应地更新。 之前的 jwks-uri (https://www.googleapis.com/robot/v1/metadata/x509/) 仅适用于服务帐户签名的 JWT。

      【讨论】:

      • 谢谢。这在一定程度上澄清了事情
      猜你喜欢
      • 1970-01-01
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 2017-07-06
      • 2018-12-29
      • 1970-01-01
      • 2020-02-29
      相关资源
      最近更新 更多