对自承载网关使用 Microsoft Entra 身份验证

可用性

重要

此功能在 API 管理的“高级”和“开发人员”层中可用。

Azure API 管理自承载网关需要与其关联的基于云的 API 管理实例建立连接,以便报告状态、检查和应用配置更新以及发送指标和事件。

除了使用网关访问令牌(身份验证密钥)连接到其基于云的 API 管理实例之外,还可以使用 Microsoft Entra 应用使自承载网关对其关联的云实例进行身份验证。 使用 Microsoft Entra 身份验证,可以配置更长的密码到期时间,并使用标准步骤来管理和轮换 Active Directory 中的密码。

方案概述

自承载网关配置 API 可以检查 Azure RBAC,以确定谁有权读取网关配置。 创建具有这些权限的 Microsoft Entra 应用后,自承载网关可以使用该应用向 API 管理实例进行身份验证。

若要启用 Microsoft Entra 身份验证,请完成以下步骤:

  1. 创建两个自定义角色,以便:
    • 允许配置 API 访问客户的 RBAC 信息
    • 授予读取自承载网关配置的权限
  2. 向 API 管理实例的托管标识授予 RBAC 访问权限
  3. 创建 Microsoft Entra 应用并向其授予读取网关配置的访问权限
  4. 使用新的配置选项部署网关

先决条件

限制说明

  • 仅支持系统分配的托管标识。

创建自定义角色

创建在后续步骤中分配的以下两个自定义角色。 可以使用以下 JSON 模板中列出的权限,通过 Azure 门户Azure CLIAzure PowerShell或其他 Azure 工具创建自定义角色。

配置自定义角色时,请使用目录的相应范围值更新 AssignableScopes 属性,例如在其中部署了 API 管理实例的订阅。

API 管理配置 API 访问验证程序服务角色

{
  "Description": "Can access RBAC permissions on the API Management resource to authorize requests in Configuration API.",
  "IsCustom": true,
  "Name": "API Management Configuration API Access Validator Service Role",
  "Permissions": [
    {
      "Actions": [
        "Microsoft.Authorization/*/read"
      ],
      "NotActions": [],
      "DataActions": [],
      "NotDataActions": []
    }
  ],
  "NotDataActions": [],
  "AssignableScopes": [
    "/subscriptions/{subscriptionID}"
  ]
}

API 管理网关配置读取者角色

{
  "Description": "Can read self-hosted gateway configuration from Configuration API",
  "IsCustom": true,
  "Name": "API Management Gateway Configuration Reader Role",
  "Permissions": [
    {
      "Actions": [],
      "NotActions": [],
      "DataActions": [
        "Microsoft.ApiManagement/service/gateways/getConfiguration/action"
      ],
      "NotDataActions": []
    }
  ],
  "NotDataActions": [],
  "AssignableScopes": [
    "/subscriptions/{subscriptionID}"
  ]
}

添加角色分配

分配 API 管理配置 API 访问验证程序服务角色

将 API 管理配置 API 访问验证程序服务角色分配给 API 管理实例的托管标识。 有关分配角色的详细步骤,请参阅使用门户分配 Azure 角色

  • 范围:在其中部署 API 管理实例的资源组或订阅
  • API 管理配置 API 访问验证程序服务角色
  • 访问权限分配对象:API 管理实例的托管标识

分配 API 管理网关配置读取者角色

步骤 1:注册 Microsoft Entra 应用

创建新的 Microsoft Entra 应用。 有关步骤,请参阅创建可访问资源的 Microsoft Entra 应用程序和服务主体。 自承载网关将使用此应用对 API 管理实例进行身份验证。

  • 生成客户端密码
  • 记下以下应用程序值,以便在下一部分部署自承载网关时使用:应用程序(客户端)ID、目录(租户)ID 和客户端密码

步骤 2:分配 API 管理网关配置读取者服务角色

向应用分配 API 管理网关配置读取者服务角色。

  • 范围:API 管理实例(或在其中部署该实例的资源组或订阅)
  • 角色:API 管理网关配置读取者角色
  • 分配访问权限:Microsoft Entra 应用

部署自承载网关

将自承载网关部署到 Kubernetes,并将 Microsoft Entra 应用注册设置添加到网关 ConfigMapdata 元素。 在以下示例 YAML 配置文件中,网关名为 mygw,文件名为 mygw.yaml

重要

如果遵循现有的 Kubernetes 部署指南

  • 请确保省略使用 kubectl create secret generic 命令存储默认身份验证密钥的步骤。
  • 将以下基本配置文件替换为 Azure 门户中为你生成的默认 YAML 文件。 以下文件添加 Microsoft Entra 配置来代替配置,以使用身份验证密钥。
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mygw-env
  labels:
    app: mygw
data:
  config.service.endpoint: "<service-name>.configuration.azure-api.cn"
  config.service.auth: azureAdApp 
  config.service.auth.azureAd.authority: "https://login.partner.microsoftonline.cn"  
  config.service.auth.azureAd.tenantId: "<Azure AD tenant ID>" 
  config.service.auth.azureAd.clientId: "<Azure AD client ID>" 
  config.service.auth.azureAd.clientSecret: "<Azure AD client secret>"
  gateway.name: <gateway-id>
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mygw
  labels:
    app: mygw
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mygw
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 25%
  template:
    metadata:
      labels:
        app: mygw
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: mygw
        image: mcr.microsoft.com/azure-api-management/gateway:v2
        ports:
        - name: http
          containerPort: 8080
        - name: https
          containerPort: 8081
          # Container port used for rate limiting to discover instances
        - name: rate-limit-dc
          protocol: UDP
          containerPort: 4290
          # Container port used for instances to send heartbeats to each other
        - name: dc-heartbeat
          protocol: UDP
          containerPort: 4291
        readinessProbe:
          httpGet:
            path: /status-0123456789abcdef
            port: http
            scheme: HTTP
          initialDelaySeconds: 0
          periodSeconds: 5
          failureThreshold: 3
          successThreshold: 1
        envFrom:
        - configMapRef:
            name: mygw-env
---
apiVersion: v1
kind: Service
metadata:
  name: mygw-live-traffic
  labels:
    app: mygw
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
  - name: http
    port: 80
    targetPort: 8080
  - name: https
    port: 443
    targetPort: 8081
  selector:
    app: mygw
---
apiVersion: v1
kind: Service
metadata:
  name: mygw-instance-discovery
  labels:
    app: mygw
  annotations:
    azure.apim.kubernetes.io/notes: "Headless service being used for instance discovery of self-hosted gateway"
spec:
  clusterIP: None
  type: ClusterIP
  ports:
  - name: rate-limit-discovery
    port: 4290
    targetPort: rate-limit-dc
    protocol: UDP
  - name: discovery-heartbeat
    port: 4291
    targetPort: dc-heartbeat
    protocol: UDP
  selector:
    app: mygw

通过以下命令将网关部署到 Kubernetes:

kubectl apply -f mygw.yaml

确认网关正在运行

  1. 运行以下命令,检查部署是否成功。 创建所有对象和初始化 Pod 可能需要一些时间。

    kubectl get deployments
    

    它应该返回

    NAME             READY   UP-TO-DATE   AVAILABLE   AGE
    <gateway-name>   1/1     1            1           18s
    
  2. 运行以下命令,检查是否已成功创建服务。 你的服务 IP 和端口与此不同。

    kubectl get services
    

    它应该返回

    NAME                                TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
    <gateway-name>-live-traffic         ClusterIP      None            <none>        4290/UDP,4291/UDP   9m1s
    <gateway-name>-instance-discovery   LoadBalancer   10.99.236.168   <pending>     80:31620/TCP,443:30456/TCP   9m1s
    
  3. 返回到 Azure 门户,选择“概述”。

  4. 确认“状态”显示绿色复选标记,后跟与 YAML 文件中指定的副本数匹配的节点计数。 此状态表示部署的自承载网关 Pod 正在成功地与 API 管理服务通信,并且具有常规的“检测信号”。显示门户中自承载网关状态的屏幕截图。

提示

  • 运行 kubectl logs deployment/<gateway-name> 命令以查看随机选择的 Pod 的日志(如果有多个 Pod)。
  • 运行 kubectl logs -h 以获得一组完整的命令选项,例如如何查看特定 Pod 或容器的日志。

后续步骤