使用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文章。
- AEM版本
-
必须在其上部署示例WKND Sites项目。
-
在本地计算机上安装Node.js以运行示例NodeJS应用程序。
开发步骤
高级开发步骤包括:
-
配置ADC项目
- 添加Assets创作API
- 将其身份验证方法配置为OAuth服务器到服务器
- 将产品配置文件与身份验证配置关联
-
配置AEM实例以启用ADC项目通信
-
开发示例NodeJS应用程序
-
验证端到端流量
配置ADC项目
配置ADC项目步骤是 重复,来自设置基于OpenAPI的AEM API。 重复添加Assets创作API并将其身份验证方法配置为OAuth服务器到服务器。
-
从Adobe Developer Console中,打开所需的项目。
-
要添加AEM API,请单击 添加API 按钮。
-
在 添加API 对话框中,按 Experience Cloud 筛选,选择 AEM Assets创作API 卡片,然后单击 下一步。
如果您需要其他基于OpenAPI的AEM API,请参阅Adobe Developer文档以查找与您的用例相匹配的API。以下示例介绍如何添加 AEM Assets创作API。
note tip TIP 如果所需的 AEM API卡 已禁用,为什么禁用了此卡? 信息显示 需要许可证 消息,原因之一可能是您没有使您的AEM as a Cloud Service环境现代化,有关详细信息,请参阅AEM as a Cloud Service环境现代化。 -
接下来,在 配置API 对话框中,选择 服务器到服务器 身份验证选项,然后单击 下一步。 服务器到服务器身份验证非常适用于需要API访问而不需要用户交互的后端服务。
note tip TIP 如果您看不到服务器到服务器身份验证选项,则意味着设置集成的用户不会作为开发人员添加到与服务相关联的产品配置文件中。 有关详细信息,请参阅启用服务器到服务器身份验证。 -
重命名凭据以便于识别(如果需要),然后单击 下一步。 出于演示目的,使用默认名称。
-
选择 AEM Assets Collaborator Users - author - Program XXX - Environment XXX Product Profile,然后单击 保存。 如您所见,仅与AEM Assets API Users服务关联的产品配置文件可供选择。
-
审查AEM API和身份验证配置。
配置AEM实例以启用ADC项目通信
按照设置基于OpenAPI的AEM API文章中的说明配置AEM实例以启用ADC项目通信。
开发示例NodeJS应用程序
让我们开发一个调用Assets创作API的示例NodeJS应用程序。
您可以使用其他编程语言(如Java、Python等)来开发应用程序。
出于测试目的,您可以使用Postman、curl或任何其他REST客户端调用AEM API。
审查API
在开发应用程序之前,让我们从Assets创作API查看 交付指定资源的元数据 端点。 API语法为:
GET https://{bucket}.adobeaemcloud.com/adobe/../assets/{assetId}/metadata
要检索特定资源的元数据,您需要bucket
和assetId
值。 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。
-
在浏览器中打开Assets创作API文档。
-
展开 元数据 部分,然后单击 交付指定资源的元数据 选项。
-
在右窗格中,单击 尝试它 按钮。
-
输入以下值:
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,并在 响应 选项卡中查看响应。
上述步骤确认了AEM as a Cloud Service环境的现代化,从而可启用AEM API访问。 它还确认已成功配置ADC项目,以及与AEM Author实例的OAuth服务器到服务器凭据ClientID通信。
示例NodeJS应用程序
让我们开发一个示例NodeJS应用程序。
若要开发应用程序,可以使用 Run-the-sample-application 或 逐步开发 说明。
-
下载示例demo-nodejs-app-to-invoke-aem-openapi应用程序zip文件并将其解压缩。
-
导航到提取的文件夹并安装依赖项。
code language-bash $ npm install
-
将
.env
文件中的占位符替换为ADC项目的OAuth服务器到服务器凭据中的实际值。 -
将
<BUCKETNAME>
文件中的<ASSETID>
和src/index.js
替换为实际值。 -
运行NodeJS应用程序。
code language-bash $ node src/index.js
-
创建新的NodeJS项目。
code language-bash $ mkdir demo-nodejs-app-to-invoke-aem-openapi $ cd demo-nodejs-app-to-invoke-aem-openapi $ npm init -y
-
安装 fetch 和 dotenv 库以分别发出HTTP请求和读取环境变量。
code language-bash $ npm install node-fetch $ npm install dotenv
-
在您喜爱的代码编辑器中打开项目并更新
package.json
文件以将type
添加到module
。code language-json { ... "version": "1.0.0", "type": "module", "main": "index.js", ... }
-
创建
.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>
-
创建
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();
-
运行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应用程序代码中的关键标注为:
-
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; }; ...
-
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凭据 选项卡中验证产品配置文件和技术帐户用户关联。
非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错误响应。
要修复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应用程序。