模拟使用 Microsoft Entra 保护的 CRUD API

生成应用时,通常会与后端 API 进行交互。 有时,这些 API 尚不可用,或者其他团队正在更新它们以满足最新要求。 为了避免等待,通常会创建一个返回所需数据的模拟 API。 虽然此方法会取消阻止你,但它要求你花时间生成最终替换为实际 API。 当需要使用 Microsoft Entra 保护 API 时,它会变得更加复杂。 为了避免浪费时间,可以使用开发代理模拟 CRUD API 并加快开发速度。

CrudApiPlugin使用 ,可以使用内存中数据存储模拟 CRUD (创建、读取、更新、删除)API。 使用简单的配置文件,可以定义模拟 API 支持的 URL 及其返回的数据。 该插件还支持 CORS,以便从客户端应用程序使用跨域。 该插件还支持Microsoft Entra 身份验证,因此可以使用 Microsoft Entra 保护模拟 API,并为应用实现与生产环境中相同的身份验证流。

场景

假设你正在构建一个应用,允许用户管理客户。 若要获取数据,需要调用 /customers 后端 API 的终结点。 API 使用 Microsoft Entra 进行保护。 为了避免等待后端团队完成其工作,你决定使用开发代理来模拟 API 并返回所需的数据。

开始之前

首先,使用客户数据创建模拟 CRUD API。 确认 API 正常工作后,可以使用 Microsoft Entra 对其进行保护。

示例 1:使用单个范围模拟使用 Microsoft Entra 保护的 CRUD API

在第一个示例中,使用单个作用域保护整个 API。 无论用户是否需要获取有关客户的信息或更新客户,他们都使用相同的权限。

customers-api.json 文件中,添加有关 Entra 的信息。

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v0.24.0/crudapiplugin.schema.json",
  "baseUrl": "https://api.contoso.com/v1/customers",
  "dataFile": "customers-data.json",
  "auth": "entra",
  "entraAuthConfig": {
    "audience": "https://api.contoso.com",
    "issuer": "https://login.microsoftonline.com/contoso.com",
    "scopes": ["api://contoso.com/user_impersonation"]
  },
  "actions": [
    {
      "action": "getAll"
    },
    {
      "action": "getOne",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]"
    },
    {
      "action": "create"
    },
    {
      "action": "merge",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]"
    },
    {
      "action": "delete",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]"
    }
  ]
}

通过将属性设置为authentra指定,API 使用 Microsoft Entra 进行保护。 在 entraAuthConfig 属性中,指定配置详细信息。 该 audience 属性指定 API 的访问群体、 issuer 属性指定令牌的颁发者,属性 scopes 指定访问 API 所需的范围。 由于在 API 文件的根级别定义 scopes ,因此所有操作都需要相同的范围。

如果尝试在没有具有指定受众、颁发者和范围的令牌的情况下调用 API,则会收到 401 Unauthorized 响应。

注意

在此阶段,开发代理不会验证令牌。 它仅检查令牌是否存在并且具有所需的受众、颁发者和范围。 在早期开发期间,当还没有真正的Microsoft Entra 应用注册并且无法获取真实令牌时,这很方便。

示例 2:使用不同操作的不同作用域模拟受 Microsoft Entra 保护的 CRUD API

在许多情况下,不同的 API 操作需要不同的权限。 例如,获取有关客户的信息可能需要与更新客户不同的权限。 在此示例中,使用不同的作用域保护不同的 API 操作。

customers-api.json 如下所示更新文件:

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v0.24.0/crudapiplugin.schema.json",
  "baseUrl": "https://api.contoso.com/v1/customers",
  "dataFile": "customers-data.json",
  "auth": "entra",
  "entraAuthConfig": {
    "audience": "https://api.contoso.com",
    "issuer": "https://login.microsoftonline.com/contoso.com"
  },
  "actions": [
    {
      "action": "getAll",
      "auth": "entra",
      "entraAuthConfig": {
        "scopes": ["api://contoso.com/customer.read"]
      }
    },
    {
      "action": "getOne",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]",
      "auth": "entra",
      "entraAuthConfig": {
        "scopes": ["api://contoso.com/customer.read"]
      }
    },
    {
      "action": "create",
      "auth": "entra",
      "entraAuthConfig": {
        "scopes": ["api://contoso.com/customer.write"]
      }
    },
    {
      "action": "merge",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]",
      "auth": "entra",
      "entraAuthConfig": {
        "scopes": ["api://contoso.com/customer.write"]
      }
    },
    {
      "action": "delete",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]",
      "auth": "entra",
      "entraAuthConfig": {
        "scopes": ["api://contoso.com/customer.write"]
      }
    }
  ]
}

这一次,不指定 scopes API 文件的根级别。 而是为每个操作指定它们。 这样,便可以保护具有不同作用域的不同操作。 例如,获取有关客户的信息需要 api://contoso.com/customer.read 范围,而更新客户需要 api://contoso.com/customer.write 范围。

验证令牌

使用开发代理可以模拟受 Microsoft Entra 保护的 CRUD API,并检查你是否使用有效的令牌。 在 Microsoft Entra 中注册应用注册时,验证令牌很方便,但团队仍在生成 API。 它允许你更准确地测试应用。

如果希望开发代理验证访问令牌,请在 entraAuthConfig 属性中添加该 validateSigningKey 属性并将其设置为 true

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v0.24.0/crudapiplugin.schema.json",
  "baseUrl": "https://api.contoso.com/v1/customers",
  "dataFile": "customers-data.json",
  "auth": "entra",
  "entraAuthConfig": {
    "audience": "https://api.contoso.com",
    "issuer": "https://login.microsoftonline.com/contoso.com",
    "scopes": ["api://contoso.com/user_impersonation"],
    "validateSigningKey": true
  },
  "actions": [
    {
      "action": "getAll"
    },
    {
      "action": "getOne",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]"
    },
    {
      "action": "create"
    },
    {
      "action": "merge",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]"
    },
    {
      "action": "delete",
      "url": "/{customer-id}",
      "query": "$.[?(@.id == {customer-id})]"
    }
  ]
}

如果尝试使用自创建令牌调用 API,则会收到 401 Unauthorized 响应。 开发代理仅允许具有由 Microsoft Entra 颁发的有效令牌的请求。

下一步

详细了解 CrudApiPlugin。

示例

另请参阅相关的开发代理示例: