通过工作负载身份联合使用令牌进行身份验证

本文档介绍了如何通过工作负载身份联合使用令牌向 Google Cloud进行身份验证。借助工作负载身份联合,您可以授予本地或多云 SAP 工作负载对 Google Cloud资源的访问权限,而无需使用服务账号密钥。

工作负载身份联合遵循 OAuth 2.0 令牌交换规范。您可以将 IdP 的凭据提供给 Security Token Service,该服务会验证凭据的身份,然后返回联合访问令牌进行交换。您可以直接将此联合访问令牌用于受支持的服务,也可以使用它来模拟服务账号并获取短期有效的访问令牌。短期有效的访问令牌可让您调用服务账号有权访问的任何 Google Cloud API。

您可以将 Workload Identity 联合使用与元数据服务器或外部身份提供方 (IdP) 搭配使用。

使用虚拟机元数据的工作负载身份联合

如果您的 SAP 系统托管在 Google Cloud 上,但由 SAP 管理,则您可以使用工作负载身份联合从 SAP 系统安全地访问其他Google Cloud 项目中的资源。 Google Cloud 借助工作负载身份联合,您的 SAP 系统可以使用虚拟机元数据向其他 Google Cloud 项目进行身份验证。这样,您就不必管理服务账号密钥,从而增强安全性并简化身份验证。

简要配置步骤如下:

  1. 在 Google Cloud中,配置工作负载身份联合
  2. 在 Google Cloud中,创建服务账号
  3. 在 Google Cloud中,向服务账号授予对 Workload Identity Federation 池的访问权限
  4. 在 ABAP SDK for Google Cloud 中,配置客户端密钥

配置工作负载身份联合

如需获得配置工作负载身份联合所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理访问权限

如需配置工作负载身份联合,请执行以下步骤:

  1. 在 Google Cloud 控制台中,进入新建工作负载提供方和池页面。

    转到“新建工作负载提供方和池”

  2. 创建身份池部分中,输入以下字段的值:

    • 名称:池的名称。该名称还用作池 ID。池 ID 创建后便无法更改。
    • 说明:描述池用途的文本。
  3. 点击继续

  4. 向池添加提供方下,将元数据服务器添加为提供方:

    1. 选择提供方字段中,选择 OpenID Connect (OIDC)
    2. 输入以下提供商详细信息:

      • 提供方名称:输入提供方的名称。
      • Issuer(网址)(签发者 [网址]):输入元数据服务器令牌网址 https://accounts.google.com
      • 受众群体:选择允许的受众群体,然后输入您需要访问的 Google Cloud 项目的 Google Cloud 项目编号。如需了解如何获取项目编号,请参阅收集 Google 元数据服务器实例的详细信息
  5. 点击继续

  6. 配置提供方属性下,执行以下操作:

    • Google 1 字段中,确保值为 google.subject
    • OIDC 1 字段中,输入 assertion.sub
  7. 点击保存

  8. 请记下以下各项:

    • 池 ID
    • 提供方 ID

    配置客户端密钥时,您需要使用这些 ID。

收集 Google 元数据服务器实例的详细信息

如需获取配置 Workload Identity 联合所需的 Google 元数据服务器实例详细信息,请执行以下步骤:

  1. 在 SAP GUI 中,执行事务代码 /GOOG/SDK_IMG

    或者,执行事务代码 SPRO,然后点击 SAP Reference IMG

  2. 依次点击 ABAP SDK for Google Cloud > 实用程序 > 获取 Google 元数据服务器实例的特定元数据值
  3. 根据需要选择相应选项:
    • 数字项目 ID
    • 默认服务账号电子邮件地址
  4. 点击执行以查看详细信息。
  5. 记下详细信息。在 Google Cloud 控制台中配置工作负载身份联合时,您需要使用这些信息。

创建服务账号

在 Google Cloud 控制台中,创建 IAM 服务账号。此服务账号必须是包含您计划通过 SDK 使用的Google Cloud API 的 Google Cloud 项目中的主账号。

  1. 在 Google Cloud 控制台中,选择您要在其中创建服务账号的项目。

    • 如果您在包含相应 API 的同一项目中创建服务账号,则该服务账号会自动添加为该项目的主账号。 Google Cloud

    • 如果您在除启用了Google Cloud API 的项目以外的项目中创建服务账号,则需要在额外步骤中将服务账号添加到该项目。如需了解详情,请参阅将服务账号添加到 Google Cloud 项目

  2. 创建一个服务账号以进行身份验证和授权来访问 Google Cloud API。

    转到“服务账号”

    如需了解如何创建服务账号,请参阅创建服务账号

  3. 在 Google Cloud 控制台中,向服务账号授予访问 API 功能所需的 IAM 角色。如需了解 API 的角色要求,请参阅各个 API 文档并遵循最小权限原则。 Google Cloud 如需详细了解 API 特定预定义角色,请参阅 IAM 基本角色和预定义角色参考文档

  4. 如果您在不同于计划通过 SDK 使用的 Google Cloud API 的项目中创建服务账号,请记下服务账号的名称。您可以在将服务账号添加到项目时指定该名称。

将服务账号添加到 Google Cloud 项目

如果您在与计划通过 SDK 使用的 Google Cloud API 的项目不同的项目中为 ABAP SDK for Google Cloud 创建了服务账号,则需要将服务账号添加到包含 Google Cloud API 的 Google Cloud 项目。

如果您在包含Google Cloud API 的同一项目中创建了服务账号,则可以跳过此步骤。

如需将现有服务账号添加到包含 Google Cloud API 的 Google Cloud 项目,请执行以下步骤:

  1. 在 Google Cloud 控制台中,进入 IAM 权限页面。

    转到 IAM 权限

  2. 确认页面顶部附近显示了包含目标Google Cloud API 的项目的名称。例如:

    项目“PROJECT_NAME”的权限

    如果未显示,请切换项目。

  3. 在 IAM 权限页面上,点击 授予访问权限

  4. 在显示的授予对“PROJECT_NAME”的访问权限对话框中,执行以下步骤:

    1. 新的主账号字段中,指定服务账号的名称。
    2. 选择角色字段中,指定相关角色。 例如,对于 Pub/Sub,如需修改主题和订阅以及发布和使用消息的权限,您可以指定 Pub/Sub Editor 角色 (roles/pubsub.editor)。

      如需详细了解 API 特定预定义角色,请参阅 IAM 基本角色和预定义角色参考文档

    3. 根据 API 使用要求添加其他角色。 我们建议您遵循最小权限原则。

    4. 点击保存。该服务账号会显示在 IAM 页面上的项目主账号列表中。

现在,该服务账号可用于访问此项目中的 Google Cloud API。

向服务账号授予对 Workload Identity 联合池的访问权限

如需模拟联合工作负载中的服务账号,请授予对服务账号的 Workload Identity User (roles/iam.workloadIdentityUser)。如需详细了解如何授予角色,请参阅管理访问权限

如需向服务账号授予对工作负载身份联合池的访问权限,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到 Workload Identity 池页面。

    转到“工作负载身份池”

  2. 选择您在配置工作负载身份联合部分中创建的工作负载身份池。

  3. 如需授予对工作负载身份池的访问权限,请点击 授予访问权限

  4. 服务账号列表中,选择有权访问 Google Cloud API 的服务账号。如果您使用多个服务账号,请在此处添加所有账号。

  5. 属性名称字段中,选择主体

  6. 属性值字段中,输入从元数据服务器检索到的服务账号电子邮件地址(用双引号括起来)。例如 "svc-acct-compute@example-project-123456.iam.gserviceaccount.com"

    如需了解如何从元数据服务器检索服务账号电子邮件地址,请参阅收集 Google 元数据服务器实例的详细信息

  7. 在随即显示的配置您的应用对话框中,点击关闭

配置客户端密钥

  1. 在 SAP GUI 中,执行事务代码 /GOOG/SDK_IMG

    或者,执行事务代码 SPRO,然后点击 SAP Reference IMG

  2. 点击 ABAP SDK for Google Cloud > Basic Settings > Configure Client Key
  3. 点击新建条目
  4. 输入以下字段的值:

    字段 说明
    Google Cloud 密钥名称 指定客户端密钥配置的名称。
    Google Cloud 服务账号名称 指定在创建服务账号步骤中为访问 API 而创建的服务账号的名称(采用电子邮件地址格式)。 Google Cloud 例如:sap-example-svc-acct@example-project-123456.iam.gserviceaccount.com
    Google Cloud 范围 指定 API 访问权限范围 https://www.googleapis.com/auth/cloud-platform
    Google Cloud 项目标识符 指定您在其中创建了工作负载身份池的 Google Cloud 项目的 ID。
    命令名称 将此字段留空。
    授权类 酌情指定身份验证类:
    • /GOOG/CL_AUTH_WIF_META_ACCESS:生成 Google 签名的 OAuth 令牌。
    • /GOOG/CL_AUTH_WIF_META_IDTOKEN:生成 Google 签名的 ID 令牌。
    令牌缓存

    此标志用于确定是否已缓存从 Google Cloud 检索到的访问令牌。

    我们建议您在完成与 Google Cloud的连接的配置和测试后启用令牌缓存。

    令牌刷新秒数 将此字段留空。
    授权参数 1 指定工作负载身份池 ID。
    授权参数 2 指定工作负载身份提供方 ID。
  5. 保存该条目。

将工作负载身份联合与外部 IdP 搭配使用

您可以将工作负载身份联合与外部 IdP(例如 Amazon Web Services [AWS])或任何支持 OpenID Connect (OIDC) 的身份提供方 (IdP)(例如 Microsoft Azure 或 SAML 2.0)搭配使用。

对于通过工作负载身份联合使用令牌进行身份验证,简要配置步骤如下:

  1. 准备外部 IdP
  2. 在 Google Cloud中,配置工作负载身份联合
  3. 在 Google Cloud中,创建服务账号
  4. 在 Google Cloud中,允许外部工作负载模拟服务账号
  5. 在 ABAP SDK for Google Cloud 中,实现 ABAP 代码以从 IdP 检索安全令牌
  6. 在 ABAP SDK for Google Cloud 中,配置客户端密钥

并非所有 Google Cloud 产品都支持工作负载身份联合。在使用工作负载身份联合设置身份验证之前,请查看支持的产品列表和限制。如需了解详情,请参阅员工身份联合:支持的产品和限制

准备外部 IdP

您需要准备 IdP,以便 SAP 工作负载获取可交换为 Google OAuth 2.0 安全令牌的凭据。

如需准备外部 IdP,请根据您的 IdP 执行步骤:

配置工作负载身份联合

在 Google Cloud中,配置工作负载身份池和提供方。

您可以配置身份池,即可让您管理外部身份的实体。您还可以配置工作负载身份池提供方,即描述 Google Cloud 和 IdP 之间关系的实体。 Google Cloud

如需配置工作负载身份联合,请根据您的外部 IdP 执行步骤:

请记下以下各项:

  • 项目编号:您在其中创建了工作负载身份池的 Google Cloud 项目的编号。
  • 池 ID:用于标识工作负载身份池的唯一 ID。
  • 提供方 ID:用于标识工作负载身份池提供方的 ID。

ABAP SDK 客户端密钥配置需要使用这些项。

创建服务账号

在 Google Cloud 控制台中,创建一个专用 IAM 服务账号以访问 Google Cloud API。此服务账号必须是包含您计划通过 SDK 使用的Google Cloud API 的 Google Cloud 项目中的主账号。

  1. 在 Google Cloud 控制台中,启用 IAM Service Account Credentials APISecurity Token Service API,以及您计划使用 SDK 访问的任何其他受支持的 API

    转到 API 库

    如需了解如何启用 Google Cloud API,请参阅启用 API

  2. 创建一个代表工作负载的服务账号

  3. 为该服务账号授予访问 API 功能所需的 IAM 角色。。如需了解 API 的角色要求,请参阅各个 API 文档并遵循最小权限原则。 Google Cloud 如需详细了解 API 特定预定义角色,请参阅查找适用于 Google Cloud API 的 IAM 角色

允许外部工作负载模拟服务账号

如需允许外部工作负载模拟服务账号,请根据您的外部 IdP 执行步骤:

实现 ABAP 代码以从 IdP 检索安全令牌

ABAP SDK for Google Cloud 提供了一个抽象类 /GOOG/CL_AUTH_WIF_BASE,它具有从 Security Token Service 检索 OAuth 2.0 安全令牌以及从 IAM Service Account Credentials API 检索 OAuth 2.0 访问令牌的逻辑。 作为开发者,您需要在命名空间中创建一个子类,该子类从抽象类 /GOOG/CL_AUTH_WIF_BASE 继承。

为了使用工作负载身份联合从 ABAP SDK for Google Cloud 调用 Cloud Run functions,SDK 提供了另一个抽象类 /GOOG/CL_AUTH_WIF_ID_TOKEN。如果您使用工作负载身份联合设置身份验证,则需要在命名空间中再创建一个子类,该子类从抽象类 /GOOG/CL_AUTH_WIF_ID_TOKEN 继承。在配置客户端密钥以调用 Cloud Run functions 时,您可以在授权类字段中指定此子类。

请务必在子类中实现 GET_EXT_IDP_TOKEN 方法,并编写从 IdP 获取安全令牌的逻辑。填充以下字段:

  • CV_TOKEN:从您的 IdP 检索到的令牌,格式为 string
  • CV_TOKEN_TYPE:从您的 IdP 检索的安全令牌的类型。支持的令牌类型包括:
    • urn:ietf:params:oauth:token-type:jwt
    • urn:ietf:params:oauth:token-type:id_token
    • urn:ietf:params:aws:token-type:aws4_request
    • urn:ietf:params:oauth:token-type:access_token
    • urn:ietf:params:oauth:token-type:saml2

然后,抽象类 /GOOG/CL_AUTH_WIF_BASE 的方法会使用在 CV_TOKENCV_TOKEN_TYPE 中填充的值来交换和检索最终的 OAuth 2.0 令牌,该令牌在 API 调用中使用。

以下示例展示了其他云服务提供商(例如 AWS 和 Azure)的方法 GET_EXT_IDP_TOKEN 的实现示例。

AWS

class ZCL_AUTH_WIF_AWS definition
  public
  inheriting from /GOOG/CL_AUTH_WIF_BASE
  final
  create public .

public section.

  types:
    BEGIN OF t_header_field,
      key type string,
      value TYPE string,
    END OF t_header_field .
  types:
    tt_header_field type STANDARD TABLE OF t_header_field WITH DEFAULT KEY .
  types:
    BEGIN OF t_token_request,
     url type string,
     method type string,
     headers type tt_header_field,
   END OF t_token_request .
protected section.

  methods GET_EXT_IDP_TOKEN
    redefinition .
private section.
ENDCLASS.



CLASS ZCL_AUTH_WIF_AWS IMPLEMENTATION.


METHOD get_ext_idp_token.
**********************************************************************
*  Copyright 2024 Google LLC                                         *
*                                                                    *
*  Licensed under the Apache License, Version 2.0 (the "License");   *
*  you may not use this file except in compliance with the License.  *
*  You may obtain a copy of the License at                           *
*      https://www.apache.org/licenses/LICENSE-2.0                   *
*  Unless required by applicable law or agreed to in writing,        *
*  software distributed under the License is distributed on an       *
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,      *
*  either express or implied.                                        *
*  See the License for the specific language governing permissions   *
*  and limitations under the License.                                *
**********************************************************************

  DATA: ls_key       TYPE /goog/client_key.

  /goog/cl_utility=>get_client_key( EXPORTING iv_keyname    = iv_keyname
                                        IMPORTING es_client_key = ls_key ).


  DATA: lv_awsdate TYPE string.

  DATA: lv_date         TYPE dats,
        lv_time         TYPE tims,
        lv_timestamp    TYPE timestampl,
        lv_tz_utc       TYPE timezone VALUE 'UTC',
        lv_awsts        TYPE string,
        lv_timechar(32) TYPE c.

  GET TIME STAMP FIELD lv_timestamp.

  CONVERT TIME STAMP lv_timestamp TIME ZONE lv_tz_utc INTO DATE lv_date TIME lv_time.
  MOVE lv_timestamp TO lv_timechar.
  CONDENSE lv_timechar.

  lv_awsdate = lv_date(4) &&
               lv_date+4(2) &&
               lv_date+6(2) &&
               'T' &&
               lv_time(2) &&
               lv_time+2(2) &&
               lv_time+4(2) &&
               'Z'.

  TRANSLATE lv_awsdate TO UPPER CASE.

  DATA: lv_lf TYPE string.
  DATA: lv_secret_key TYPE string.
  DATA: lv_accesskey TYPE string.
  DATA: lv_datepart TYPE string.
  DATA: lv_service TYPE string.
  DATA: lv_method TYPE string.

  lv_lf = cl_abap_char_utilities=>newline.
  lv_accesskey = '<Populate AWS Access Key>'.
  lv_secret_key = '<Populate AWS Secret Access Key>'.
  lv_datepart = lv_awsdate(8).
  lv_service = 'sts'.
  lv_method = 'GET'.


  DATA: lv_canonical_query_params TYPE string.
  DATA: lv_host TYPE string.
  DATA: lv_region TYPE string.
  DATA: lv_canonical_resource_path TYPE string.

  lv_canonical_query_params = 'Action=GetCallerIdentity&Version=2011-06-15'.
  lv_host = 'sts.amazonaws.com'.
  lv_region = '<Populate your AWS Region>'.   "Example: 'us-east-1'
  lv_canonical_resource_path = '/'.

  DATA: lv_canonical_header_names TYPE string.
  DATA: lv_canonical_headers TYPE string.

  lv_canonical_header_names = 'host;x-amz-date'.
  lv_canonical_headers = 'host:' && lv_host && lv_lf && 'x-amz-date:' && lv_awsdate && lv_lf.

  DATA: lv_canonical_request TYPE string.

  CONCATENATE lv_method lv_lf
              lv_canonical_resource_path lv_lf
              lv_canonical_query_params lv_lf
              lv_canonical_headers lv_lf
              lv_canonical_header_names
              INTO lv_canonical_request.

  DATA: lv_canonical_request_hash TYPE string.

  TRY.
      cl_abap_message_digest=>calculate_hash_for_char(
       EXPORTING
         if_algorithm = 'SHA-256'
         if_data = lv_canonical_request
       IMPORTING
         ef_hashstring = lv_canonical_request_hash ).
    CATCH cx_abap_message_digest.
      "Handle error
      RETURN.
  ENDTRY.

  TRANSLATE lv_canonical_request_hash TO LOWER CASE.

  DATA: lv_algorithm TYPE string.

  lv_algorithm = 'AWS4-HMAC-SHA256'.

  DATA: lv_credential_scope TYPE string.

  CONCATENATE lv_datepart '/' lv_region '/' lv_service '/' 'aws4_request' INTO lv_credential_scope.

  DATA: lv_string_to_sign TYPE string.

  CONCATENATE lv_algorithm lv_lf
              lv_awsdate lv_lf
              lv_credential_scope lv_lf
              lv_canonical_request_hash
              INTO lv_string_to_sign.

  DATA: lv_awskey TYPE string.

  CONCATENATE 'AWS4' lv_secret_key INTO lv_awskey.

  DATA: lv_ksecret TYPE xstring.

  TRY.
      lv_ksecret = cl_abap_hmac=>string_to_xstring( lv_awskey ).
    CATCH cx_abap_message_digest .
      "Handle error
      RETURN.
  ENDTRY.

  DATA: lv_kdate  TYPE xstring.
  TRY.
      cl_abap_hmac=>calculate_hmac_for_char(
        EXPORTING
           if_algorithm = 'SHA256'
           if_key = lv_ksecret
           if_data = lv_datepart
        IMPORTING
           ef_hmacxstring = lv_kdate ).
    CATCH cx_abap_message_digest. "
      "Handle error
      RETURN.
  ENDTRY.

  DATA: lv_kregion TYPE xstring.
  TRY.
      cl_abap_hmac=>calculate_hmac_for_char(
        EXPORTING
           if_algorithm = 'SHA256'
           if_key = lv_kdate
           if_data = lv_region
        IMPORTING
             ef_hmacxstring = lv_kregion ).
    CATCH cx_abap_message_digest.
      "Handle error
      RETURN.
  ENDTRY.

  DATA: lv_kservice TYPE xstring.
  TRY.
      cl_abap_hmac=>calculate_hmac_for_char(
         EXPORTING
           if_algorithm = 'SHA256'
           if_key = lv_kregion
           if_data = lv_service
           IMPORTING
             ef_hmacxstring = lv_kservice ).
    CATCH cx_abap_message_digest.
      "Handle error
      RETURN.
  ENDTRY.

  DATA: lv_ksigningkey TYPE xstring.
  TRY.
      cl_abap_hmac=>calculate_hmac_for_char(
         EXPORTING
           if_algorithm = 'SHA256'
           if_key = lv_kservice
           if_data = 'aws4_request'
         IMPORTING
             ef_hmacxstring = lv_ksigningkey ).
    CATCH cx_abap_message_digest.
      "Handle error
      RETURN.
  ENDTRY.

  DATA: lv_stringtosign TYPE string.

  lv_stringtosign = 'AWS4-HMAC-SHA256' && lv_lf &&
                   lv_awsdate && lv_lf &&
                   lv_datepart && '/' &&
                   lv_region && '/' &&
                   lv_service && '/aws4_request' && lv_lf &&
                   lv_canonical_request_hash.

  DATA: lv_ssignature TYPE string.

  TRY.
      cl_abap_hmac=>calculate_hmac_for_char(
         EXPORTING
           if_algorithm = 'SHA256'
           if_key = lv_ksigningkey
           if_data = lv_stringtosign
         IMPORTING
           ef_hmacstring = lv_ssignature ).
    CATCH cx_abap_message_digest.
      "Handle error
      RETURN.
  ENDTRY.

  TRANSLATE lv_ssignature TO LOWER CASE.

  DATA: lv_authorization_header TYPE string.

  lv_authorization_header = 'AWS4-HMAC-SHA256 Credential=' &&
                            lv_accesskey && '/' &&
                            lv_credential_scope &&
                            ', SignedHeaders=' &&
                            lv_canonical_header_names &&
                            ', Signature=' &&
                            lv_ssignature.

  DATA: ls_token_request TYPE t_token_request.

  ls_token_request-url = 'https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15'.
  ls_token_request-method = 'POST'.

  DATA: ls_header_field TYPE t_header_field.
  ls_header_field-key = 'Authorization'.
  ls_header_field-value = lv_authorization_header.
  APPEND ls_header_field TO ls_token_request-headers.

  CLEAR: ls_header_field.
  ls_header_field-key = 'host'.
  ls_header_field-value = 'sts.amazonaws.com'.
  APPEND ls_header_field TO ls_token_request-headers.

  CLEAR: ls_header_field.
  ls_header_field-key = 'x-amz-date'.
  ls_header_field-value = lv_awsdate.
  APPEND ls_header_field TO ls_token_request-headers.

  CLEAR: ls_header_field.
  ls_header_field-key = 'x-goog-cloud-target-resource'.
  ls_header_field-value = '//iam.googleapis.com/projects/' &&
                               ls_key-project_id &&
                               '/locations/global/workloadIdentityPools/' &&
                               ls_key-auth_param1 &&
                               '/providers/' &&
                               ls_key-auth_param2.
  APPEND ls_header_field TO ls_token_request-headers.

  cv_token = /ui2/cl_json=>serialize(  ls_token_request ).
  cv_token_type = 'urn:ietf:params:aws:token-type:aws4_request'.

ENDMETHOD.
ENDCLASS.

Azure

class ZCL_AUTH_WIF_AZURE definition
  public
  inheriting from /GOOG/CL_AUTH_WIF_BASE
  final
  create public .

public section.
protected section.

  methods GET_EXT_IDP_TOKEN
    redefinition .
private section.
ENDCLASS.



CLASS ZCL_AUTH_WIF_AZURE IMPLEMENTATION.


  METHOD GET_EXT_IDP_TOKEN.
**********************************************************************
*  Copyright 2024 Google LLC                                         *
*                                                                    *
*  Licensed under the Apache License, Version 2.0 (the "License");   *
*  you may not use this file except in compliance with the License.  *
*  You may obtain a copy of the License at                           *
*      https://www.apache.org/licenses/LICENSE-2.0                   *
*  Unless required by applicable law or agreed to in writing,        *
*  software distributed under the License is distributed on an       *
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,      *
*  either express or implied.                                        *
*  See the License for the specific language governing permissions   *
*  and limitations under the License.                                *
**********************************************************************

    TYPES:
      BEGIN OF t_azure_resp,
        access_token TYPE string,
      END OF t_azure_resp.

    DATA: lo_client TYPE REF TO if_http_client.

    DATA: lv_url type string.
    lv_url = 'http://169.254.169.254/metadata/identity/oauth2/token?resource=<APP_ID_URI>&api-version=2018-02-01'.
    "Replace <APP_ID_URI> with the value of Application ID URI of the application that you've configured for workload identity federation.

    cl_http_client=>create_by_url(
       EXPORTING
         url                        = lv_url
       IMPORTING
         client                     = lo_client
       EXCEPTIONS
         argument_not_found         = 1
         plugin_not_active          = 2
         internal_error             = 3
         pse_not_found              = 4
         pse_not_distrib            = 5
         pse_errors                 = 6
         oa2c_set_token_error       = 7
         oa2c_missing_authorization = 8
         oa2c_invalid_config        = 9
         oa2c_invalid_parameters    = 10
         oa2c_invalid_scope         = 11
         oa2c_invalid_grant         = 12
         OTHERS                     = 13 ).

    IF sy-subrc <> 0.
      RETURN.
    ENDIF.

    lo_client->request->set_method( 'GET' ).
    lo_client->request->set_header_field( name = 'Metadata' value = 'true' ).

    lo_client->send(
      EXCEPTIONS
        http_communication_failure = 1
        http_invalid_state         = 2
        http_processing_failed     = 3
        http_invalid_timeout       = 4
        OTHERS                     = 5 ).

    lo_client->propertytype_logon_popup = lo_client->co_disabled.

    lo_client->receive(
      EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3 ).

    DATA: lv_json TYPE string.

    lv_json = lo_client->response->get_cdata( ).

    DATA: ls_azure_resp TYPE t_azure_resp.

    /goog/cl_json=>deserialize(
      EXPORTING
        json             = lv_json
      CHANGING
        data             = ls_azure_resp ).
    cv_token = ls_azure_resp-access_token.
    cv_token_type = 'urn:ietf:params:oauth:token-type:jwt'.

  ENDMETHOD.
ENDCLASS.

配置客户端密钥

  1. 在 SAP GUI 中,执行事务代码 /GOOG/SDK_IMG

    或者,执行事务代码 SPRO,然后点击 SAP Reference IMG

  2. 点击 ABAP SDK for Google Cloud > Basic Settings > Configure Client Key
  3. 点击新建条目
  4. 输入以下字段的值:

    字段 说明
    Google Cloud 密钥名称 指定客户端密钥配置的名称。
    Google Cloud 服务账号名称 指定在创建服务账号步骤中为访问 API 而创建的服务账号的名称(采用电子邮件地址格式)。 Google Cloud 例如:sap-example-svc-acct@example-project-123456.iam.gserviceaccount.com
    Google Cloud 范围 指定 API 访问权限范围 https://www.googleapis.com/auth/cloud-platform
    Google Cloud 项目标识符 指定您在其中创建了工作负载身份池的 Google Cloud 项目的 ID。
    命令名称 将此字段留空。
    授权类 指定子类,其中包含类 /GOOG/CL_AUTH_WIF_BASE 的实现。如需了解详情,请参阅实现 ABAP 代码以从 IdP 检索安全令牌
    令牌缓存

    此标志用于确定是否已缓存从 Google Cloud 检索到的访问令牌。

    我们建议您在完成与 Google Cloud的连接的配置和测试后启用令牌缓存。

    令牌刷新秒数 将此字段留空。
    授权参数 1 指定工作负载身份池 ID。
    授权参数 2 指定工作负载身份提供方 ID。
  5. 保存该条目。

获取支持

如果您在解决 ABAP SDK for Google Cloud 问题时需要帮助,请执行以下操作: