管理来自服务的产品授权

如果你有应用和加载项目录,则可以使用 Microsoft Store 集合 APIMicrosoft Store 购买 API,从服务中访问这些产品的权利信息。 权利表示客户有权使用通过 Microsoft Store 发布的应用或加载项。

这些 API 由 REST 方法组成,旨在供开发者用于由跨平台服务支持的加载项目录。 通过这些 API,可以执行以下操作:

注意

Microsoft应用商店收集 API 和购买 API 使用Microsoft标识平台(Entra ID)身份验证来访问客户所有权信息。 若要使用这些 API,您或您的组织必须具有 Entra ID 租户,并且您必须具有租户的 全局管理员 权限。 如果您已经使用 Microsoft 365 或其他 Microsoft 商业服务,那么您已经拥有 Entra ID 租户。

Microsoft.StoreServices 库

为了帮助简化身份验证流并调用 Microsoft Store Services,请查看 Github 上的 Microsoft.StoreServices 项目和示例。 Microsoft.StoreServices 库将帮助管理身份验证密钥,并提供包装 API 来调用用于管理产品的 Microsoft Store Services。 示例项目重点介绍了服务如何使用 Microsoft.StoreServices 库、管理易耗品、协调退款购买、续订过期凭据等的示例逻辑。 示例包含分步配置指南,用于在电脑或 Azure 上设置示例服务。

概述

以下步骤介绍了使用 Microsoft 应用商店收集 API 和购买 API 的端到端过程:

  1. 在 Entra ID中配置应用程序。
  2. 在合作伙伴中心将 Entra ID 应用程序 ID 与应用相关联
  3. 在你的服务中,创建表示你的发布者身份的 Entra ID 访问令牌
  4. 在客户端 Windows 应用中,创建一个Microsoft应用商店 ID 密钥,该密钥表示当前用户的标识,并将此密钥传递回服务。

此端到端过程涉及执行不同任务的两个软件组件:

  • 你的服务。 这是一个应用程序,可在业务环境的上下文中安全地运行,并且可以使用你选择的任何开发平台来实现它。 您的服务负责创建在此场景中所需的 Entra ID 访问令牌,并调用 Microsoft 应用商店的集合 API 和购买 API 的 REST URI。
  • 你的客户端 Windows 应用。 这是您希望访问和管理客户权限信息(包括该应用的附加组件)的应用程序。 此应用负责创建你需要的 Microsoft 商店 ID 密钥,以便从你的服务调用 Microsoft 商店集合 API 和购买 API。

步骤 1:在 Entra ID 中配置应用程序

在使用 Microsoft 应用商店集合 API 或购买 API 之前,必须创建 Entra ID Web 应用程序、检索应用程序的租户 ID 和应用程序 ID,并生成密钥。 Entra ID Web 应用程序表示要从中调用 Microsoft 应用商店集合 API 或购买 API 的服务。 需要租户 ID、应用程序 ID 和密钥来生成需要调用 API 的 Entra ID 访问令牌。

  1. 如果尚未执行此操作,请按照快速入门:向 Microsoft 标识平台注册应用程序中的说明,向 Entra ID 注册 Web 应用/API 应用程序。

    注意

    注册应用程序时,必须选择 Web 应用/API 作为应用程序类型,以便检索应用程序的密钥(也称为 客户端密码)。 若要调用 Microsoft 应用商店集合 API 或购买 API,您必须在后续步骤中从 Entra ID 申请访问令牌时提供客户端密钥。

  2. Azure 管理门户中,导航到 Microsoft Entra ID。 选择你的租户后,单击“管理”下的左侧导航窗格中的 应用注册项目,然后选择你的应用程序。

  3. 你被带到应用程序的主注册页。 在此页上,复制 应用程序 ID 值以供以后使用。

  4. 创建稍后将需要的密钥(这全部称为 客户端密码)。 在左侧窗格中,依次单击“设置”、“密钥”。 在此页上,完成 创建密钥的步骤。 复制此密钥供以后使用。

步骤 2:在合作伙伴中心将 Entra ID 应用程序 ID 与客户端应用相关联

在使用 Microsoft Store 集合 API 或购买 API 配置您的应用或加载项的所有权和购买之前,必须在合作伙伴中心将 Entra 应用程序 ID 与该应用(或包含加载项的应用)相关联。

注意

只需一次执行此任务。 拥有租户 ID、应用程序 ID 和客户端密码后,可以随时重复使用这些值,以创建新的 Entra ID 访问令牌。

  1. 登录到 合作伙伴中心 并选择你的应用。
  2. 转到 服务>产品集合和购买 页,将 Entra 应用程序 ID 输入到可用的 客户端 ID 字段中。

步骤 3:创建 Entra ID 访问令牌

在检索 Microsoft Store ID 密钥或调用 Microsoft Store 集合 API 或购买 API 之前,您的服务必须创建多种不同的 Entra ID 访问令牌来表示您的发布者身份。 每个令牌将用于不同的 API。 每个令牌的生存期为 60 分钟,可以在令牌过期后对其进行刷新。

重要

仅在服务的上下文中创建 Entra ID 访问令牌,而不要在应用中创建。 如果将客户端密钥发送到应用程序,可能会导致泄露。

了解不同令牌和受众 URI

根据要在 Microsoft Store 集合 API 或购买 API 中调用的方法,你必须创建两个或三个不同的令牌。 每个访问令牌都与不同的访问群体 URI 相关联。

  • 在所有情况下,都必须使用 https://onestore.microsoft.com 受众 URI 创建令牌。 在后续步骤中,你将把此令牌传递给 Microsoft Store 集合 API 或购买 API 中方法的授权标头。

    重要

    仅使用安全存储在服务中的访问令牌来访问 https://onestore.microsoft.com 受众。 将访问令牌向不属于您服务的受众公开,可能使您的服务容易受到重播攻击。

  • 如果要调用 Microsoft Store 集合 API 中的方法来查询用户拥有的产品将可消费产品报告为已完成,则还必须使用 https://onestore.microsoft.com/b2b/keys/create/collections 受众 URI 创建令牌。 在后续步骤中,您将此令牌传递给 Windows SDK 中的客户端方法,以请求可用于 Microsoft Store 集合 API 的 Microsoft Store ID 密钥。

  • 如果要调用 Microsoft Store 购买 API 中的方法,向用户授予免费产品获取用户的订阅,或 更改用户订阅的计费状态,则还必须使用 https://onestore.microsoft.com/b2b/keys/create/purchase 受众 URI 创建令牌。 在后面的步骤中,你将此令牌传递给 Windows SDK 中的客户端方法,以请求可与 Microsoft 应用商店购买 API 一起使用的 Microsoft 应用商店 ID 密钥。

创建令牌

若要创建访问令牌,请在您的服务中使用 OAuth 2.0 API,并按照 服务到服务调用中使用客户端凭据的指令,将 HTTP POST 发送到 https://login.microsoftonline.com/<tenant_id>/oauth2/token 终结点。 下面是一个示例请求。

POST https://login.microsoftonline.com/<tenant_id>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8

grant_type=client_credentials
&client_id=<your_client_id>
&client_secret=<your_client_secret>
&resource=https://onestore.microsoft.com

对于每个令牌,请指定以下参数数据:

  • 对于 client_idclient_secret 参数,请为从 Azure 管理门户检索的应用程序指定应用程序 ID 和客户端密码。 需要这两个参数才能创建具有Microsoft应用商店收集 API 或购买 API 所需的身份验证级别的访问令牌。

  • 对于 resource 参数,请指定上一部分列出的其中一个受众 URI,具体取决于所创建的访问令牌类型。

访问令牌过期后,可以按照 此处的说明刷新它。 有关访问令牌结构的更多详细信息,请参阅 支持的令牌和声明类型

步骤 4:创建Microsoft应用商店 ID 密钥

在Microsoft应用商店收集 API 或购买 API 中调用任何方法之前,应用必须创建Microsoft应用商店 ID 密钥并将其发送到服务。 此密钥是一个 JSON Web 令牌(JWT),表示要访问其产品所有权信息的用户的标识。 有关此密钥中的声明的详细信息,请参阅Microsoft应用商店 ID 密钥中的声明

目前,创建Microsoft应用商店 ID 密钥的唯一方法是从应用中的客户端代码调用通用 Windows 平台 (UWP) API。 生成的密钥表示当前登录到设备上的 Microsoft Store 的用户的标识。

注意

每个Microsoft应用商店 ID 密钥有效期为 30 天。 在密钥过期之前,可以 续订密钥。 建议续订Microsoft应用商店 ID 密钥,而不是创建新密钥。

为 Microsoft 应用商店集合 API 创建 Microsoft 应用商店 ID 密钥

按照以下步骤创建可用于 Microsoft Store 集合 API 的 Microsoft Store ID 密钥,以查询用户拥有的产品将可消费产品报告为已完成

  1. 将具有受众 URI 值 https://onestore.microsoft.com/b2b/keys/create/collections 的 Entra ID 访问令牌从你的服务传递到客户端应用。 这是您在步骤 3中创建的令牌之一

  2. 在应用代码中,调用以下方法之一来检索Microsoft应用商店 ID 密钥:

  • 如果你的应用使用 Windows.Services.Store 命名空间中的 StoreContext 类来管理应用内购买,请使用 StoreContext.GetCustomerCollectionsIdAsync 方法。

  • 如果你的应用使用 Windows.ApplicationModel.Store 命名空间中的 CurrentApp 类来管理应用内购买,请使用 CurrentApp.GetCustomerCollectionsIdAsync 方法。

    将 Entra ID 访问令牌传递给方法的 serviceTicket 参数。 如果您作为当前应用的发布者,维护您所管理服务中的匿名用户 ID,那么您也可以将用户 ID 传递给 publisherUserId 参数,以将当前用户与新的 Microsoft Store ID 密钥关联(用户 ID 将被嵌入到密钥中)。 否则,如果不需要将用户 ID 与 Microsoft 应用商店 ID 密钥相关联,可以将任何字符串值传递给 publisherUserId 参数。

  1. 应用成功创建Microsoft应用商店 ID 密钥后,将密钥传递回服务。

为 Microsoft Store 购买 API 创建 Microsoft Store ID 密钥

按照以下步骤创建Microsoft应用商店 ID 密钥,可与 Microsoft 应用商店购买 API 一起使用,向用户授予免费产品,获取用户的订阅,或 更改用户订阅的计费状态。

  1. 将具有受众 URI 值 https://onestore.microsoft.com/b2b/keys/create/purchase 的 Entra ID 访问令牌从你的服务传递到客户端应用。 这是你在步骤 3中创建的令牌之一

  2. 在应用代码中,调用以下方法之一来检索Microsoft应用商店 ID 密钥:

  • 如果你的应用使用 Windows.Services.Store 命名空间中的 StoreContext 类来管理应用内购买,请使用 StoreContext.GetCustomerPurchaseIdAsync 方法。

  • 如果你的应用使用 Windows.ApplicationModel.Store 命名空间中的 CurrentApp 类来管理应用内购买,请使用 CurrentApp.GetCustomerPurchaseIdAsync 方法。

    将 Entra ID 访问令牌传递给方法的 serviceTicket 参数。 如果您作为当前应用的发布者,在所管理的服务上下文中维护匿名用户 ID,则还可以将用户 ID 传递给 publisherUserId 参数,以便将当前用户与新的 Microsoft 应用商店 ID 密钥关联(用户 ID 将嵌入到密钥中)。 否则,如果不需要将用户 ID 与 Microsoft 应用商店 ID 密钥相关联,可以将任何字符串值传递给 publisherUserId 参数。

  1. 应用成功创建Microsoft应用商店 ID 密钥后,将密钥传递回服务。

示意图

下图演示了创建Microsoft应用商店 ID 密钥的过程。

创建 Windows 应用商店 ID 密钥

Microsoft Store ID 密钥中的声明

Microsoft Store ID 密钥是一个 JSON Web 令牌(JWT),用于表示你想要访问其产品所有权信息的用户身份。 使用 Base64 解码时,Microsoft应用商店 ID 密钥包含以下声明。

  • iat:标识颁发密钥的时间。 此声明可用于确定令牌的年龄。 此值表示为纪元时间。
  • iss:标识颁发者。 此值与 aud 声明具有相同的值。
  • aud:标识受众。 必须是下列值之一:https://collections.mp.microsoft.com/v6.0/keyshttps://purchase.mp.microsoft.com/v6.0/keys
  • exp:标识密钥的到期时间,过期时间之后,密钥将不再被接受处理,除非用于续订密钥。 此声明的值表示为纪元时间。
  • nbf:标识将接受令牌进行处理的时间。 此声明的值表示为纪元时间。
  • http://schemas.microsoft.com/marketplace/2015/08/claims/key/clientId:标识开发人员的客户端 ID。
  • http://schemas.microsoft.com/marketplace/2015/08/claims/key/payload:一个不透明的有效负载(经过加密和 Base64 编码),其中包含仅供 Microsoft Store 服务使用的信息。
  • http://schemas.microsoft.com/marketplace/2015/08/claims/key/userId:用于在服务上下文中标识当前用户的用户 ID。 传递到用于创建密钥的 方法中的可选 publisherUserId 参数的值与此相同。
  • http://schemas.microsoft.com/marketplace/2015/08/claims/key/refreshUri:可用于续订密钥的 URI。

下面是已解码Microsoft应用商店 ID 密钥标头的示例。

{
    "typ":"JWT",
    "alg":"RS256",
    "x5t":"agA_pgJ7Twx_Ex2_rEeQ2o5fZ5g"
}

下面是已解码Microsoft应用商店 ID 密钥声明集的示例。

{
    "http://schemas.microsoft.com/marketplace/2015/08/claims/key/clientId": "1d5773695a3b44928227393bfef1e13d",
    "http://schemas.microsoft.com/marketplace/2015/08/claims/key/payload": "ZdcOq0/N2rjytCRzCHSqnfczv3f0343wfSydx7hghfu0snWzMqyoAGy5DSJ5rMSsKoQFAccs1iNlwlGrX+/eIwh/VlUhLrncyP8c18mNAzAGK+lTAd2oiMQWRRAZxPwGrJrwiq2fTq5NOVDnQS9Za6/GdRjeiQrv6c0x+WNKxSQ7LV/uH1x+IEhYVtDu53GiXIwekltwaV6EkQGphYy7tbNsW2GqxgcoLLMUVOsQjI+FYBA3MdQpalV/aFN4UrJDkMWJBnmz3vrxBNGEApLWTS4Bd3cMswXsV9m+VhOEfnv+6PrL2jq8OZFoF3FUUpY8Fet2DfFr6xjZs3CBS1095J2yyNFWKBZxAXXNjn+zkvqqiVRjjkjNajhuaNKJk4MGHfk2rZiMy/aosyaEpCyncdisHVSx/S4JwIuxTnfnlY24vS0OXy7mFiZjjB8qL03cLsBXM4utCyXSIggb90GAx0+EFlVoJD7+ZKlm1M90xO/QSMDlrzFyuqcXXDBOnt7rPynPTrOZLVF+ODI5HhWEqArkVnc5MYnrZD06YEwClmTDkHQcxCvU+XUEvTbEk69qR2sfnuXV4cJRRWseUTfYoGyuxkQ2eWAAI1BXGxYECIaAnWF0W6ThweL5ZZDdadW9Ug5U3fZd4WxiDlB/EZ3aTy8kYXTW4Uo0adTkCmdLibw=",
    "http://schemas.microsoft.com/marketplace/2015/08/claims/key/userId": "infusQMLaYCrgtC0d/SZWoPB4FqLEwHXgZFuMJ6TuTY=",
    "http://schemas.microsoft.com/marketplace/2015/08/claims/key/refreshUri": "https://collections.mp.microsoft.com/v6.0/b2b/keys/renew",
    "iat": 1733526889,
    "iss": "https://collections.mp.microsoft.com/v6.0/keys",
    "aud": "https://collections.mp.microsoft.com/v6.0/keys",
    "exp": 1733523289,
    "nbf": 1736118889
}