Ignacio Lozano,Karine Pires和Chris Sterling为这篇博文做出了贡献。
在当今的数字化转型世界中,API 几乎存在于每个软件产品中。许多团队负责部署和管理大型 API 组合。但是,API 的规模和复杂性也使控制和管理访问变得复杂。具体而言,了解粒度用法并发现见解和利用率可能很困难。使用 API Portal for VMware Tanzu 和 Spring Cloud Gateway for Kubernetes 进入 API 密钥管理,旨在解决此问题等。这篇文章主要探讨 API 密钥管理的功能。有关其他功能的信息,请查看最新文档。
API 密钥管理功能
作为 API 使用者,您可以为使用适用于 VMware Tanzu 的 API 门户配置的单个或多个 API 组生成 API 密钥。您可以查看当前处于活动状态的密钥列表,并在不再需要它们时将其撤销。任何生成的密钥都存储在一个秘密存储中,配置的 Spring Cloud Gateway for Kubernetes 可以从中读取和验证任何传入的请求。HashiCorp Vault 是秘密管理领域的领先提供商,因此被选为 API 密钥管理的首次集成。
创建 API 密钥模式视图
作为 API 管理员,除了上述所有功能外,您还可以查看 API 门户实例中所有用户生成的所有密钥的详细视图。对于每个密钥,您可以查看密钥名称、颁发日期、所有者以及使用该密钥可访问的 API 组。还可以撤销任何用户在 API 门户中创建的密钥。通过检查来自 OIDC 身份提供程序的 ID 令牌中的声明,将用户标识为 API 管理员。有关配置 API 门户以检查正确声明的更多详细信息,请参阅文档中的 API 管理器部分。
API 管理器的 API 密钥列表视图
API 管理入门
先决条件:
- 启用了 SSO 的适用于 VMware Tanzu v1.1.x 或更高版本的 API 门户(下载|安装说明)
- Spring Cloud Gateway for Kubernetes v1.1.x 或更高版本(下载|安装说明)
- 访问 HashiCorp 保管库实例(如果您还没有实例访问权限,请按照以下说明创建一个实例。
注意:本指南的其余部分将假设API门户安装在“api-portal”命名空间中,Spring Cloud Gateway for Kubernetes安装在“spring-cloud-gateway”命名空间中,Vault安装在“vault”命名空间中。请根据需要替换自定义命名空间。
配置库访问
以下是 Vault 与 API 门户和 Spring Cloud Gateway for Kubernetes 集成所需的不同部分的鸟瞰图。您需要为这两种产品中的每个产品创建保险柜访问策略,在其各自的命名空间中创建服务帐号,并将这些服务账户附加到保险柜访问策略。
如果您愿意,也可以使用 Vault UI 设置下一组命令。首先从命令行访问 Vault 实例,并为要存储的 API 密钥配置专用路径。
vault secrets enable -path=api-portal-keys kv-v2
接下来,为此确切路径配置访问策略。API 门户需要完全访问此路径,而 Spring Cloud Gateway for Kubernetes 只需要此路径中的读取和列出权限。创建“API 门户策略”。
(
cat << EOF
path "api-portal-keys/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "api-portal-keys/metadata/*" {
capabilities = ["list", "delete"]
}
EOF
) | vault policy write api-portal-policy -
接下来,创建“网关策略”以读取所有 API 密钥。
(
cat << EOF
path "api-portal-keys/data/*" {
capabilities = ["read"]
}
path "api-portal-keys/metadata/*" {
capabilities = ["list"]
}
EOF
) | vault policy write gateway-policy -
或者,您可以创建“网关策略”以仅读取属于特定 API 组 ID 的 API 密钥。
(
cat << EOF
path "api-portal-keys/data/my-group-id*" {
capabilities = ["read"]
}
path "api-portal-keys/metadata/my-group-id*" {
capabilities = ["list"]
}
EOF
) | vault policy write gateway-policy -
将 Vault 连接到您的 Kubernetes 集群
为了使您的部署能够访问保管库,您需要使用 Kubernetes 服务帐户令牌的 Kubernetes 身份验证方法。
vault auth enable kubernetes
vault write auth/kubernetes/config \
token_reviewer_jwt="<your reviewer service account JWT>" \
kubernetes_host=https://192.168.99.100:<your TCP port or blank for 443> \
kubernetes_ca_cert=@ca.crt
如果您的保管库实例与 API 门户和 Spring 云网关位于同一集群中,则可以运行:
vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
接下来,需要创建将命名空间服务帐户绑定到已创建的策略的角色。您可以在保险柜中创建“api-portal-role”,以允许在附加到保险柜中“api-portal-policy”的“api-portal”命名空间中名为“api-portal-sa”的服务帐号。
vault write auth/kubernetes/role/api-portal-role \
bound_service_account_names=api-portal-sa \
bound_service_account_namespaces=api-portal \
policies=api-portal-policy \
ttl=24h
同样,您可以在“spring-cloud-gateway”命名空间中为名为“gateway-sa”的服务帐户创建“网关角色”。
vault write auth/kubernetes/role/gateway-role \
bound_service_account_names=gateway-sa \
bound_service_account_namespaces=spring-cloud-gateway \
policies=gateway-policy \
ttl=24h
您可以在各自的命名空间中创建上述服务帐户。API 门户还可以在安装过程中自动创建服务帐户。
kubectl -n api-portal create serviceaccount api-portal-sa
配置 API 门户以启用 API 密钥管理
在与 API 门户的安装脚本结合使用的 values.yml 文件中,添加以下属性以启用和配置 API 密钥:
apiKey:
enabled: true
vault:
url: "<Your vault url or http://vault.vault.svc:8200/ if Vault is installed in the same cluster>"
role: api-portal-role
path: api-portal-keys
serviceAccount:
create: true # Note: This will automatically create the service account
name: api-portal-sa
apiPortalServer:
sourceUrls: "<Your scg-operator url>/openapi"
sso:
enabled: true
secretName: <Your sso secret name>
创建启用了 API 密钥的 Spring 云网关
最后一步是使用保管库详细信息创建网关,以允许网关读取并列出存储的 API 密钥。使用以下详细信息创建一个 scg.yaml 并应用它。如果添加“serverUrl”,则还需要创建一个入口,以将流量从该主机路由到 my-gateway 服务。
---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
name: my-gateway
spec:
api:
groupId: my-group-id
serverUrl: my-gateway.my-example-domain.com # Optional but recommended for testing the gateway
cors: # Optional but needed for API portal’s “Try it out” feature
allowedOrigins:
- "<My API portal’s domain>"
allowedMethods:
- "GET"
allowedHeaders:
- "*"
serviceAccount:
name: gateway-sa
extensions:
secretsProviders:
- name: vault-api-keys
vault:
roleName: gateway-role
path: api-portal-keys
filters:
apiKey:
enabled: true
secretsProviderName: vault-api-keys
---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
name: my-routes
spec:
routes:
- predicates:
- Path=/github/
uri: https://github.com
---
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayMapping
metadata:
name: my-mapping
spec:
gatewayRef:
name: my-gateway
routeConfigRef:
name: my-routes
现在,任何像“my-routes”映射到“my-gateway”的路由都需要一个额外的标头“X-API-Key:<API Key Value>”才能传入。
使用 API 门户创建 API 密钥
为了使API门户能够识别“my-gateway”及其路由,您需要公开Spring Cloud Gateway运营商的OpenAPI端点,也可以选择公开my-gateway服务。您可以使用此处的说明创建入口,或使用其他方法公开操作员和网关。
然后,可以修改在 API 门户的 values.yml 中配置的源 URL,并重新运行安装脚本。如果希望 API 门户信任自签名或不安全的 TLS 证书,可以设置“信任不安全源 URL”属性。
apiPortalServer:
sourceUrls: "https://<my-scg-operator-url>/openapi”
trustInsecureSourceUrls: true # false by default
最后,登录到 API 门户用户界面,导航到“API 密钥”选项卡,然后单击“+ API 密钥”按钮。为密钥命名,选择组,生成密钥,然后复制令牌。确保令牌安全,因为您只能复制一次。
试试看
从 API 门户主页上的 API 列表中,单击组卡片,该卡片将转到 Swagger UI 页面。在那里,单击授权按钮并将 API 密钥粘贴到标头值字段中。
用于在请求中传递 API 密钥的授权模式
接下来,单击“试用”按钮并点击“执行”以查看 200 OK 响应。
使用授权执行 API 后响应 200 OK
您还可以使用 cURL、HTTP 或 Postman 等 HTTP 客户端来测试路由。
curl -X GET my-gateway.my-example-domain.com/github --header "X-API-Key:<my-api-key>”
< HTTP/1.1 200 OK
...
您还可以看到,如果没有标头,请求将失败:
curl -X GET my-gateway.my-example-domain.com/github
< HTTP/1.1 401 Unauthorized
...