使用OAuth服务器到服务器身份验证调用基于OpenAPI的AEM API

了解如何使用​ OAuth服务器到服务器 ​身份验证,从自定义应用程序在AEM as a Cloud Service上调用基于OpenAPI的AEM API。

OAuth服务器到服务器身份验证非常适用于需要API访问而不进行用户交互的后端服务。 它使用OAuth 2.0 client_credentials ​授权类型来验证客户端应用程序。

你将学到的内容 what-you-learn

在本教程中,您将学习如何:

  • 配置Adobe Developer Console (ADC)项目以使用​ OAuth服务器到服务器身份验证 ​访问Assets创作API。

  • 开发一个示例NodeJS应用程序,该应用程序调用Assets创作API以检索特定资源的元数据。

开始之前,请确保已查看以下内容:

先决条件

要完成本教程,您需要:

  • 包含以下内容的现代化AEM as a Cloud Service环境:

    • AEM版本2024.10.18459.20241031T210302Z或更高版本。
    • 新样式产品配置文件(如果环境是在2024年11月之前创建的)

    有关更多详细信息,请参阅设置基于OpenAPI的AEM API文章。

  • 必须在其上部署示例WKND Sites项目。

  • 访问Adobe Developer Console

  • 在本地计算机上安装Node.js以运行示例NodeJS应用程序。

开发步骤

高级开发步骤包括:

  1. 配置ADC项目

    1. 添加Assets创作API
    2. 将其身份验证方法配置为OAuth服务器到服务器
    3. 将产品配置文件与身份验证配置关联
  2. 配置AEM实例以启用ADC项目通信

  3. 开发示例NodeJS应用程序

  4. 验证端到端流量

配置ADC项目

配置ADC项目步骤是​ 重复,来自设置基于OpenAPI的AEM API。 重复添加Assets创作API并将其身份验证方法配置为OAuth服务器到服务器。

TIP
确保您已完成​ 设置基于OpenAPI的AEM API ​文章中的启用AEM API访问步骤。 如果没有该选项,“服务器到服务器”身份验证选项将不可用。
  1. Adobe Developer Console中,打开所需的项目。

  2. 要添加AEM API,请单击​ 添加API ​按钮。

    添加API

  3. 在​ 添加API ​对话框中,按​ Experience Cloud ​筛选,选择​ AEM Assets创作API ​卡片,然后单击​ 下一步
    如果您需要其他基于OpenAPI的AEM API,请参阅Adobe Developer文档以查找与您的用例相匹配的API。

    以下示例介绍如何添加​ AEM Assets创作API

    添加AEM API

    note tip
    TIP
    如果所需的​ AEM API卡 ​已禁用,为什么禁用了此卡? ​信息显示​ 需要许可证 ​消息,原因之一可能是您没有使您的AEM as a Cloud Service环境现代化,有关详细信息,请参阅AEM as a Cloud Service环境现代化
  4. 接下来,在​ 配置API ​对话框中,选择​ 服务器到服务器 ​身份验证选项,然后单击​ 下一步。 服务器到服务器身份验证非常适用于需要API访问而不需要用户交互的后端服务。

    选择身份验证

    note tip
    TIP
    如果您看不到服务器到服务器身份验证选项,则意味着设置集成的用户不会作为开发人员添加到与服务相关联的产品配置文件中。 有关详细信息,请参阅启用服务器到服务器身份验证
  5. 重命名凭据以便于识别(如果需要),然后单击​ 下一步。 出于演示目的,使用默认名称。

    重命名凭据

  6. 选择​ AEM Assets Collaborator Users - author - Program XXX - Environment XXX Product Profile,然后单击​ 保存。 如您所见,仅与AEM Assets API Users服务关联的产品配置文件可供选择。

    选择产品配置文件

  7. 审查AEM API和身份验证配置。

    AEM API配置

    身份验证配置

配置AEM实例以启用ADC项目通信

按照设置基于OpenAPI的AEM API文章中的说明配置AEM实例以启用ADC项目通信。

开发示例NodeJS应用程序

让我们开发一个调用Assets创作API的示例NodeJS应用程序。

您可以使用其他编程语言(如Java、Python等)来开发应用程序。

出于测试目的,您可以使用Postmancurl或任何其他REST客户端调用AEM API。

审查API

在开发应用程序之前,让我们从Assets创作API查看​ 交付指定资源的元数据 ​端点。 API语法为:

GET https://{bucket}.adobeaemcloud.com/adobe/../assets/{assetId}/metadata

要检索特定资源的元数据,您需要bucketassetId值。 bucket是没有Adobe域名(.adobeaemcloud.com)的AEM实例名称,例如author-p63947-e1420428

assetId是前缀为urn:aaid:aem:的资源的JCR UUID,例如urn:aaid:aem:a200faf1-6d12-4abc-bc16-1b9a21f870da。 有多种方法可获取assetId

  • 附加AEM资源路径.json扩展以获取资源元数据。 例如,https://author-p63947-e1420429.adobeaemcloud.com/content/dam/wknd-shared/en/adventures/cycling-southern-utah/adobestock-221043703.jpg.json并查找jcr:uuid属性。

  • 或者,您可以通过检查浏览器元素检查器中的资产来获取assetId。 查找data-id="urn:aaid:aem:..."属性。

    检查资产

使用浏览器调用API

在开发应用程序之前,让我们使用​ API文档 ​中的尝试它功能调用API。

  1. 在浏览器中打开Assets创作API文档

  2. 展开​ 元数据 ​部分,然后单击​ 交付指定资源的元数据 ​选项。

  3. 在右窗格中,单击​ 尝试它 ​按钮。
    API文档

  4. 输入以下值:

    table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 5-row-3
    分区 参数
    分段 AEM实例名称不带Adobe域名(.adobeaemcloud.com),例如author-p63947-e1420428
    安全性 持有者令牌 使用ADC项目的OAuth服务器到服务器凭据中的访问令牌。
    安全性 X-Api-Key 使用ADC项目的OAuth服务器到服务器凭据中的ClientID值。
    参数 资产ID AEM中资源的唯一标识符,例如urn:aaid:aem:a200faf1-6d12-4abc-bc16-1b9a21f870da
    参数 X-Adobe-Accept-Experimental 1

    调用API — 访问令牌

    调用API — 输入值

  5. 单击​ 发送 ​以调用API,并在​ 响应 ​选项卡中查看响应。

    调用API — 响应

上述步骤确认了AEM as a Cloud Service环境的现代化,从而可启用AEM API访问。 它还确认已成功配置ADC项目,以及与AEM Author实例的OAuth服务器到服务器凭据ClientID通信。

示例NodeJS应用程序

让我们开发一个示例NodeJS应用程序。

若要开发应用程序,可以使用​ Run-the-sample-application ​或​ 逐步开发 ​说明。

Run-the-sample-application
  1. 下载示例demo-nodejs-app-to-invoke-aem-openapi应用程序zip文件并将其解压缩。

  2. 导航到提取的文件夹并安装依赖项。

    code language-bash
    $ npm install
    
  3. .env文件中的占位符替换为ADC项目的OAuth服务器到服务器凭据中的实际值。

  4. <BUCKETNAME>文件中的<ASSETID>src/index.js替换为实际值。

  5. 运行NodeJS应用程序。

    code language-bash
    $ node src/index.js
    
逐步开发
  1. 创建新的NodeJS项目。

    code language-bash
    $ mkdir demo-nodejs-app-to-invoke-aem-openapi
    $ cd demo-nodejs-app-to-invoke-aem-openapi
    $ npm init -y
    
  2. 安装​ fetch ​和​ dotenv ​库以分别发出HTTP请求和读取环境变量。

    code language-bash
    $ npm install node-fetch
    $ npm install dotenv
    
  3. 在您喜爱的代码编辑器中打开项目并更新package.json文件以将type添加到module

    code language-json
    {
        ...
        "version": "1.0.0",
        "type": "module",
        "main": "index.js",
        ...
    }
    
  4. 创建.env文件并添加以下配置。 将占位符替换为ADC项目的OAuth服务器到服务器凭据中的实际值。

    code language-properties
    CLIENT_ID=<ADC Project OAuth Server-to-Server credential ClientID>
    CLIENT_SECRET=<ADC Project OAuth Server-to-Server credential Client Secret>
    SCOPES=<ADC Project OAuth Server-to-Server credential Scopes>
    
  5. 创建src/index.js文件并添加以下代码,然后将<BUCKETNAME><ASSETID>替换为实际值。

    code language-javascript
    // Import the dotenv configuration to load environment variables from the .env file
    import "dotenv/config";
    
    // Import the fetch function to make HTTP requests
    import fetch from "node-fetch";
    
    // REPLACE THE FOLLOWING VALUES WITH YOUR OWN
    const bucket = "<BUCKETNAME>"; // Bucket name is the AEM instance name (e.g. author-p63947-e1420428)
    const assetId = "<ASSETID>"; // Asset ID is the unique identifier for the asset in AEM (e.g. urn:aaid:aem:a200faf1-6d12-4abc-bc16-1b9a21f870da). You can get it by inspecting the asset in browser's element inspector, look for data-id="urn:aaid:aem:..."
    
    // Load environment variables for authentication
    const clientId = process.env.CLIENT_ID; // Adobe IMS client ID
    const clientSecret = process.env.CLIENT_SECRET; // Adobe IMS client secret
    const scopes = process.env.SCOPES; // Scope for the API access
    
    // Adobe IMS endpoint for obtaining an access token
    const adobeIMSV3TokenEndpointURL =
    "https://ims-na1.adobelogin.com/ims/token/v3";
    
    // Function to obtain an access token from Adobe IMS
    const getAccessToken = async () => {
        console.log("Getting access token from IMS"); // Log process initiation
        //console.log("Client ID: " + clientId); // Display client ID for debugging purposes
    
        // Configure the HTTP POST request to fetch the access token
        const options = {
            method: "POST",
            headers: {
            "Content-Type": "application/x-www-form-urlencoded", // Specify form data content type
            },
            // Send client ID, client secret, and scopes as the request body
            body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scope=${scopes}`,
        };
    
        // Make the HTTP request to fetch the access token
        const response = await fetch(adobeIMSV3TokenEndpointURL, options);
    
        //console.log("Response status: " + response.status); // Log the HTTP status for debugging
    
        const responseJSON = await response.json(); // Parse the JSON response
    
        console.log("Access token received"); // Log success message
    
        // Return the access token
        return responseJSON.access_token;
    };
    
    // Function to retrieve metadata for a specific asset from AEM
    const getAssetMetadat = async () => {
        // Fetch the access token using the getAccessToken function
        const accessToken = await getAccessToken();
    
        console.log("Getting asset metadata from AEM");
    
        // Invoke the Assets Author API to retrieve metadata for a specific asset
        const resp = await fetch(
            `https://${bucket}.adobeaemcloud.com/adobe/../assets/${assetId}/metadata`, // Construct the URL with bucket and asset ID
            {
            method: "GET",
            headers: {
                "If-None-Match": "string", // Header to handle caching (not critical for this tutorial)
                "X-Adobe-Accept-Experimental": "1", // Header to enable experimental Adobe API features
                Authorization: "Bearer " + accessToken, // Provide the access token for authorization
                "X-Api-Key": clientId, // Include the OAuth S2S ClientId for identification
            },
            }
        );
    
        const data = await resp.json(); // Parse the JSON response
    
        console.log("Asset metadata received"); // Log success message
        console.log(data); // Display the retrieved metadata
    };
    
    // Call the getAssets function to start the process
    getAssetMetadat();
    
  6. 运行NodeJS应用程序。

    code language-bash
    $ node src/index.js
    

API响应

成功执行后,控制台中会显示API响应。 响应包含指定资源的元数据。

{
  "assetId": "urn:aaid:aem:9c09ff70-9ee8-4b14-a5fa-ec37baa0d1b3",
  "assetMetadata": {
    ...
    "dc:title": "A Young Mountain Biking Couple Takes A Minute To Take In The Scenery",
    "xmp:CreatorTool": "Adobe Photoshop Lightroom Classic 7.5 (Macintosh)",
    ...
  },
  "repositoryMetadata": {
    ...
    "repo:name": "adobestock-221043703.jpg",
    "repo:path": "/content/dam/wknd-shared/en/adventures/cycling-southern-utah/adobestock-221043703.jpg",
    "repo:state": "ACTIVE",
    ...
  }
}

恭喜!您已成功使用OAuth服务器到服务器身份验证从自定义应用程序中调用基于OpenAPI的AEM API。

查看应用程序代码

示例NodeJS应用程序代码中的关键标注为:

  1. IMS身份验证:使用ADC项目中的OAuth服务器到服务器凭据设置获取访问令牌。

    code language-javascript
    // Function to obtain an access token from Adobe IMS
    const getAccessToken = async () => {
    
        // Configure the HTTP POST request to fetch the access token
        const options = {
            method: "POST",
            headers: {
            "Content-Type": "application/x-www-form-urlencoded", // Specify form data content type
            },
            // Send client ID, client secret, and scopes as the request body
            body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scope=${scopes}`,
        };
    
        // Make the HTTP request to fetch the access token from Adobe IMS token endpoint https://ims-na1.adobelogin.com/ims/token/v3
        const response = await fetch(adobeIMSV3TokenEndpointURL, options);
    
        const responseJSON = await response.json(); // Parse the JSON response
    
        // Return the access token
        return responseJSON.access_token;
    };
    ...
    
  2. API调用:调用Assets创作API,通过提供授权访问令牌来检索特定资源的元数据。

    code language-javascript
    // Function to retrieve metadata for a specific asset from AEM
    const getAssetMetadat = async () => {
        // Fetch the access token using the getAccessToken function
        const accessToken = await getAccessToken();
    
        console.log("Getting asset metadata from AEM");
    
        // Invoke the Assets Author API to retrieve metadata for a specific asset
        const resp = await fetch(
            `https://${bucket}.adobeaemcloud.com/adobe/../assets/${assetId}/metadata`, // Construct the URL with bucket and asset ID
            {
            method: "GET",
            headers: {
                "If-None-Match": "string", // Header to handle caching (not critical for this tutorial)
                "X-Adobe-Accept-Experimental": "1", // Header to enable experimental Adobe API features
                Authorization: "Bearer " + accessToken, // Provide the access token for authorization
                "X-Api-Key": clientId, // Include the OAuth S2S ClientId for identification
            },
            }
        );
    
        const data = await resp.json(); // Parse the JSON response
    
        console.log("Asset metadata received"); // Log success message
        console.log(data); // Display the retrieved metadata
    };
    ...
    

在幕后工作

成功调用API后,将在AEM创作服务中创建表示ADC项目的OAuth服务器到服务器凭据的用户,以及匹配产品配置文件和服务配置的用户组。 技术帐户用户 ​与产品配置文件和​ 服务 ​用户组相关联,该用户组具有​ 读取 ​资产元数据的必要权限。

要验证技术帐户用户和用户组的创建情况,请执行以下步骤:

  • 在ADC项目中,导航到​ OAuth服务器到服务器 ​凭据配置。 记下​ 技术帐户电子邮件 ​值。

    技术帐户电子邮件

  • 在AEM Author服务中,导航到​ 工具 > 安全性 > 用户,并搜索​ 技术帐户电子邮件 ​值。

    技术帐户用户

  • 单击技术帐户用户以查看用户详细信息,如​ ​成员资格。 如下所示,技术帐户用户与​ AEM Assets Collaborator Users - author - Program XXX - Environment XXX ​和​ AEM Assets Collaborator Users - Service ​用户组相关联。

    技术帐户用户成员资格

  • 请注意,技术帐户用户与​ AEM Assets Collaborator Users - author - Program XXX - Environment XXX ​产品配置文件相关联。 产品配置文件与​ AEM Assets API用户 ​和​ AEM Assets Collaborator用户 ​服务相关联。

    技术帐户用户产品配置文件

  • 可以在​ 产品配置文件 ​的​ API凭据 ​选项卡中验证产品配置文件和技术帐户用户关联。

    产品配置文件API凭据

非GET请求出现403错误

要​ 读取 ​资源元数据,为OAuth服务器到服务器凭据创建的技术帐户用户通过服务用户组(例如,AEM Assets Collaborator Users - Service)具有必要权限。

但是,要​ 创建、更新、删除 (CUD)资产元数据,技术帐户用户需要其他权限。 您可以通过调用具有非GET请求(例如,PATCH、DELETE)的API来验证它,并观察到403错误响应。

让我们调用​ PATCH ​请求以更新资源元数据并观察403错误响应。

  • 在浏览器中打开Assets创作API文档

  • 输入以下值:

    table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 5-row-3 6-row-3 7-row-3
    分区 参数
    存储桶 AEM实例名称不带Adobe域名(.adobeaemcloud.com),例如author-p63947-e1420428
    安全性 持有者令牌 使用ADC项目的OAuth服务器到服务器凭据中的访问令牌。
    安全性 X-Api-Key 使用ADC项目的OAuth服务器到服务器凭据中的ClientID值。
    正文 [{ "op": "add", "path": "foo","value": "bar"}]
    参数 资产ID AEM中资源的唯一标识符,例如urn:aaid:aem:a200faf1-6d12-4abc-bc16-1b9a21f870da
    参数 X-Adobe-Accept-Experimental *
    参数 X-Adobe-Accept-Experimental 1
  • 单击​ 发送 ​以调用​ PATCH ​请求并观察403错误响应。

    调用API - PATCH请求

要修复403错误,您有两个选项:

  • 在ADC项目中,使用相应的产品配置文件更新OAuth服务器到服务器凭据的产品配置文件,该产品配置文件具有​ 创建、更新、删除 (CUD)资产元数据的必要权限,例如,AEM管理员 — 作者 — 程序XXX — 环境XXX。 有关详细信息,请参阅如何 — API的已连接凭据和产品配置文件管理文章。

  • 使用AEM项目,在AEM Author中更新关联的AEM Service用户组(例如,AEM Assets Collaborator Users - Service)的权限,以允许创建、更新和删除​ (CUD)资源元数据。 ​有关详细信息,请参阅如何 — AEM服务用户组权限管理文章。

摘要

在本教程中,您已了解如何从自定义应用程序调用基于OpenAPI的AEM API。 您已启用AEM API访问,并创建和配置了Adobe Developer Console (ADC)项目。
在ADC项目中,您添加了AEM API,配置了其身份验证类型,并关联了产品配置文件。 您还配置了AEM实例以启用ADC项目通信,并开发了一个调用Assets创作API的示例NodeJS应用程序。

其他资源

recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69