This is the multi-page printable view of this section. Click here to print.
保护 Dapr 部署
1 - 设置和配置 mTLS 证书
Dapr 支持通过 Dapr 控制平面 Sentry 服务对 Dapr 实例之间的通信进行传输中加密,该服务是一个中央证书颁发机构(CA)。
Dapr 允许操作员和开发者引入自己的证书,或者让 Dapr 自动创建并持久化自签名的根证书和颁发者证书。
有关 mTLS 的详细信息,请阅读安全概念部分。
如果未提供自定义证书,Dapr 会自动创建并持久化有效期为一年自签名证书。 在 Kubernetes 中,证书会被持久化到一个 secret 中,该 secret 位于 Dapr 系统 pod 的命名空间内,仅对它们可访问。 在自托管模式下,证书会被持久化到磁盘。
控制平面 Sentry 服务配置
mTLS 设置位于 Dapr 控制平面配置文件中。例如,当将 Dapr 控制平面部署到 Kubernetes 时,该配置文件会自动创建,然后您可以对其进行编辑。以下文件显示了配置资源中 mTLS 的可用设置,部署在 daprsystem 命名空间中:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "24h"
allowedClockSkew: "15m"
此文件显示了默认的 daprsystem 配置设置。下面的示例展示了如何在 Kubernetes 和自托管模式下更改并将此配置应用于控制平面 Sentry 服务。
Kubernetes
使用配置资源设置 mTLS
在 Kubernetes 中,Dapr 会创建一个默认的控制平面配置资源,并启用 mTLS。
Sentry 服务(证书颁发机构系统 pod)在使用 Helm 和使用 dapr init --kubernetes 的 Dapr CLI 时都会安装。
您可以使用以下命令查看控制平面配置资源:
kubectl get configurations/daprsystem --namespace <DAPR_NAMESPACE> -o yaml。
要更改控制平面配置资源,请运行以下命令进行编辑:
kubectl edit configurations/daprsystem --namespace <DAPR_NAMESPACE>
保存更改后,执行控制平面的滚动更新:
kubectl rollout restart deploy/dapr-sentry -n <DAPR_NAMESPACE>
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
注意:控制平面 Sidecar Injector 服务不需要重新部署
使用 Helm 禁用 mTLS
控制平面将继续使用 mTLS
kubectl create ns dapr-system
helm install \
--set global.mtls.enabled=false \
--namespace dapr-system \
dapr \
dapr/dapr
使用 CLI 禁用 mTLS
控制平面将继续使用 mTLS
dapr init --kubernetes --enable-mtls=false
查看日志
要查看 Sentry 服务日志,请运行以下命令:
kubectl logs --selector=app=dapr-sentry --namespace <DAPR_NAMESPACE>
自带证书
使用 Helm,您可以提供 PEM 编码的根证书、颁发者证书和私钥,这些将被填充到 Sentry 服务使用的 Kubernetes secret 中。
避免停机
为了避免在轮换过期证书时出现停机,请始终使用相同的私用根密钥对证书进行签名。注意:此示例使用 OpenSSL 命令行工具,这是一个广泛分发的软件包,可以通过软件包管理器在 Linux 上轻松安装。在 Windows 上,可以使用 chocolatey 安装 OpenSSL。在 MacOS 上可以使用 brew brew install openssl 安装
创建用于生成证书的配置文件,这对于生成带有 SAN(主题备用名称)扩展字段的 v3 证书是必需的。首先将以下内容保存到名为 root.conf 的文件中:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = VA
L = Daprville
O = dapr.io/sentry
OU = dapr.io/sentry
CN = cluster.local
[v3_req]
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = cluster.local
为 issuer.conf 重复此操作,将相同的内容粘贴到文件中,但在 basicConstraints 行的末尾添加 pathlen:0,如下所示:
basicConstraints = critical, CA:true, pathlen:0
运行以下命令生成根证书和密钥
# 跳过以下行以重用现有的根密钥,这是轮换过期证书所必需的
openssl ecparam -genkey -name prime256v1 | openssl ec -out root.key
openssl req -new -nodes -sha256 -key root.key -out root.csr -config root.conf -extensions v3_req
openssl x509 -req -sha256 -days 365 -in root.csr -signkey root.key -outform PEM -out root.pem -extfile root.conf -extensions v3_req
接下来运行以下命令生成颁发者证书和密钥:
# 跳过以下行以重用现有的颁发者密钥,这是轮换过期证书所必需的
openssl ecparam -genkey -name prime256v1 | openssl ec -out issuer.key
openssl req -new -sha256 -key issuer.key -out issuer.csr -config issuer.conf -extensions v3_req
openssl x509 -req -in issuer.csr -CA root.pem -CAkey root.key -CAcreateserial -outform PEM -out issuer.pem -days 365 -sha256 -extfile issuer.conf -extensions v3_req
安装 Helm 并通过配置将根证书、颁发者证书和颁发者密钥传递给 Sentry:
kubectl create ns dapr-system
helm install \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
使用 CLI 升级根和颁发者证书(推荐)
下面的 CLI 命令可用于在 Kubernetes 集群中续订根和颁发者证书。
生成全新的证书
- 下面的命令生成全新的根和颁发者证书,由新生成的私用根密钥签名。
注意:
Dapr Sentry 服务和其余控制平面服务必须重启才能读取新证书。可以通过向命令提供--restart标志来完成。
dapr mtls renew-certificate -k --valid-until <days> --restart
- 下面的命令生成全新的根和颁发者证书,由提供的私用根密钥签名。
注意:如果您现有的部署证书由此相同的私用根密钥签名,则
Dapr Sentry 服务无需重启即可读取这些新证书。
dapr mtls renew-certificate -k --private-key <private_key_file_path> --valid-until <days>
使用提供的自定义证书续订证书
要更新 Kubernetes 集群中提供的证书,可以使用下面的 CLI 命令。
注意 - 它不支持
valid-until标志来指定新证书的有效期。
dapr mtls renew-certificate -k --ca-root-certificate <ca.crt> --issuer-private-key <issuer.key> --issuer-public-certificate <issuer.crt> --restart
重启启用 Dapr 的 pod
无论使用哪个命令来续订证书,都必须重启所有启用 Dapr 的 pod。 由于证书不匹配,在所有部署成功重启之前,您可能会遇到一些停机时间。kubectl rollout restart deploy/myapp
使用 Kubectl 更新根或颁发者证书
如果根证书或颁发者证书即将过期,您可以更新它们并重启所需的系统服务。
轮换证书时避免停机
为了避免在轮换过期证书时出现停机,您的新证书必须与之前的证书使用相同的私用根密钥签名。使用 Dapr 生成的自签名证书目前无法实现这一点。Dapr 生成的自签名证书
- 通过将以下 YAML 保存到文件(例如
clear-trust-bundle.yaml)并应用此 secret 来清除现有的 Dapr Trust Bundle secret。
apiVersion: v1
kind: Secret
metadata:
name: dapr-trust-bundle
labels:
app: dapr-sentry
data:
kubectl apply -f `clear-trust-bundle.yaml` -n <DAPR_NAMESPACE>
- 重启 Dapr Sentry 服务。这将生成新的证书包并更新
dapr-trust-bundleKubernetes secret。
kubectl rollout restart -n <DAPR_NAMESPACE> deployment/dapr-sentry
- Sentry 服务重启后,重启 Dapr 控制平面的其余部分以获取新的 Dapr Trust Bundle。
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
kubectl rollout restart deploy/dapr-sidecar-injector -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-scheduler-server -n <DAPR_NAMESPACE>
- 重启您的 Dapr 应用程序以获取最新的信任包。
启用 mTLS 时可能出现的应用程序停机
使用 mTLS 的服务间调用的部署重启将失败,直到被调用服务也已重启(从而加载新的 Dapr Trust Bundle)。此外,在应用程序重启以加载新的 Dapr Trust Bundle 之前,placement 服务将无法分配新的 actor(而现有 actor 不受影响)。kubectl rollout restart deployment/mydaprservice1 kubectl deployment/myotherdaprservice2
自定义证书(自带)
首先,使用自带证书中的步骤颁发新证书。
现在您已拥有新证书,请使用 Helm 升级证书:
helm upgrade \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
或者,您可以更新保存它们的 Kubernetes secret:
kubectl edit secret dapr-trust-bundle -n <DAPR_NAMESPACE>
用新证书中的相应值替换 Kubernetes secret 中的 ca.crt、issuer.crt 和 issuer.key 键。
注意:值必须是 base64 编码的
如果您使用相同的私钥签名了新的证书根,Dapr Sentry 服务将自动获取新证书。您可以使用 kubectl rollout restart 零停机地重启应用程序部署。只要在原始证书过期之前重启部署,就不必一次性重启所有部署。
如果您使用不同的私钥签名了新的证书根,则必须重启 Dapr Sentry 服务,然后是 Dapr 控制平面服务的其余部分。
kubectl rollout restart deploy/dapr-sentry -n <DAPR_NAMESPACE>
Sentry 完全重启后,运行:
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
接下来,您必须重启所有启用 Dapr 的 pod。 推荐的做法是对部署执行滚动重启:
kubectl rollout restart deploy/myapp
由于证书不匹配,在所有部署成功重启(从而加载新的 Dapr 证书)之前,您可能会遇到潜在的停机时间。
Kubernetes 视频演示
观看此视频以了解如何在 Kubernetes 上更新 mTLS 证书
为 Dapr 控制平面 mTLS 证书过期设置监控
从 mTLS 根证书过期前 30 天开始,Dapr sentry 服务将每小时发出警告级别日志,表明根证书即将过期。
作为在 生产环境中运行 Dapr 的操作最佳实践,我们建议配置对这些特定 sentry 服务日志的监控,以便您了解即将到来的证书过期。
"Dapr root certificate expiration warning: certificate expires in 2 days and 15 hours"
证书过期后,您将看到以下消息:
"Dapr root certificate expiration warning: certificate has expired."
在 Kubernetes 中,您可以这样查看 sentry 服务日志:
kubectl logs deployment/dapr-sentry -n dapr-system
日志输出将如下所示:"
{"instance":"dapr-sentry-68cbf79bb9-gdqdv","level":"warning","msg":"Dapr root certificate expiration warning: certificate expires in 2 days and 15 hours","scope":"dapr.sentry","time":"2022-04-01T23:43:35.931825236Z","type":"log","ver":"1.6.0"}
作为提醒您即将到来的证书过期的附加工具,从 1.7.0 版本开始,CLI 现在会在您与基于 Kubernetes 的部署交互时打印证书过期状态。
示例:
dapr status -k
NAME NAMESPACE HEALTHY STATUS REPLICAS VERSION AGE CREATED
dapr-operator dapr-system True Running 1 1.15.1 4m 2025-02-19 17:36.26
dapr-placement-server dapr-system True Running 1 1.15.1 4m 2025-02-19 17:36.27
dapr-dashboard dapr-system True Running 1 0.15.0 4m 2025-02-19 17:36.27
dapr-sentry dapr-system True Running 1 1.15.1 4m 2025-02-19 17:36.26
dapr-scheduler-server dapr-system True Running 3 1.15.1 4m 2025-02-19 17:36.27
dapr-sidecar-injector dapr-system True Running 1 1.15.1 4m 2025-02-19 17:36.26
⚠ Dapr root certificate of your Kubernetes cluster expires in 2 days. Expiry date: Mon, 04 Apr 2025 15:01:03 UTC.
Please see docs.dapr.io for certificate renewal instructions to avoid service interruptions.
自托管
运行控制平面 Sentry 服务
要运行 Sentry 服务,您可以从源代码构建,或从这里下载发布二进制文件。
从源代码构建时,请参阅此指南以了解如何构建 Dapr。
其次,为 Sentry 服务创建一个目录以创建自签名根证书:
mkdir -p $HOME/.dapr/certs
使用以下命令在本地运行 Sentry 服务:
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local
如果成功,Sentry 服务将运行并在给定目录中创建根证书。 此命令使用默认配置值,因为未给出自定义配置文件。请参阅下面有关如何使用自定义配置启动 Sentry 服务的信息。
使用配置资源设置 mTLS
Dapr 实例配置
在自托管模式下运行 Dapr 时,默认情况下禁用 mTLS。您可以通过创建以下配置文件来启用它:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
除了 Dapr 配置外,您还需要为每个 Dapr sidecar 实例提供 TLS 证书。您可以通过在运行 Dapr 实例之前设置以下环境变量来做到这一点:
export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt`
export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt`
export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key`
export NAMESPACE=default
$env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt)
$env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt)
$env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key)
$env:NAMESPACE="default"
如果使用 Dapr CLI,请将 Dapr 指向上面的配置文件以运行启用 mTLS 的 Dapr 实例:
dapr run --app-id myapp --config ./config.yaml node myapp.js
如果直接使用 daprd,请使用以下标志启用 mTLS:
daprd --app-id myapp --enable-mtls --sentry-address localhost:50001 --config=./config.yaml
Sentry 服务配置
以下是 Sentry 的配置示例,将工作负载证书 TTL 更改为 25 秒:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "25s"
要使用自定义配置启动 Sentry 服务,请使用以下标志:
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local --config=./config.yaml
自带证书
要提供您自己的凭证,请创建 ECDSA PEM 编码的根和颁发者证书并将它们放置在文件系统上。
使用 --issuer-credentials 标志告诉 Sentry 服务从哪里加载证书。
下一个示例创建根和颁发者证书并使用 Sentry 服务加载它们。
注意:此示例使用 step 工具创建证书。您可以从这里安装 step 工具。Windows 二进制文件可在这里获取
创建根证书:
step certificate create cluster.local ca.crt ca.key --profile root-ca --no-password --insecure
创建颁发者证书:
step certificate create cluster.local issuer.crt issuer.key --ca ca.crt --ca-key ca.key --profile intermediate-ca --not-after 8760h --no-password --insecure
这将创建根和颁发者证书和密钥。
将 ca.crt、issuer.crt 和 issuer.key 放在所需路径中(下面的示例中为 $HOME/.dapr/certs),并启动 Sentry:
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local
更新根或颁发者证书
如果根证书或颁发者证书即将过期,您可以更新它们并重启所需的系统服务。
要让 Dapr 生成新证书,请删除 $HOME/.dapr/certs 处的现有证书并重启 sentry 服务以生成新证书。
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local --config=./config.yaml
要替换为您自己的证书,首先使用自带证书中的步骤生成新证书。
将 ca.crt、issuer.crt 和 issuer.key 复制到每个配置的系统服务的文件系统路径,并重启进程或容器。
默认情况下,系统服务将在 /var/run/dapr/credentials 中查找凭证。上面的示例使用 $HOME/.dapr/certs 作为自定义位置。
注意:如果您使用不同的私钥签名了证书根,请重启 Dapr 实例。
关于证书轮换的社区电话视频
观看此视频了解如果您的证书即将过期如何执行证书轮换。
Sentry 令牌验证器
令牌通常用于身份验证和授权目的。 令牌验证器是负责验证这些令牌的有效性和真实性的组件。 例如,在 Kubernetes 环境中,令牌验证的常见方法是通过 Kubernetes 绑定服务账户机制。 此验证器针对 Kubernetes 检查绑定的服务账户令牌,以确保其合法性。
Sentry 服务可以配置为:
- 除了 Kubernetes 绑定服务账户验证器之外,启用额外的令牌验证器
- 替换自托管模式下默认启用的
insecure验证器
Sentry 令牌验证器用于将额外的非 Kubernetes 客户端加入以 Kubernetes 模式运行的 Dapr 集群,或替换自托管模式下不安全的"允许所有"验证器以启用适当的身份验证。 除非您使用的是特殊的部署场景,否则预计您不需要配置令牌验证器。
目前唯一支持的令牌验证器是
jwks验证器。
JWKS
jwks 验证器使 Sentry 服务能够使用 JWKS 端点验证 JWT 令牌。
令牌的内容_必须_包含与 Dapr 客户端的 SPIFFE 身份匹配的 sub 声明,采用相同的 Dapr 格式 spiffe://<trust-domain>/ns/<namespace>/<app-id>。
令牌的受众必须是 Sentry 身份的 SPIFFE ID,例如 spiffe://cluster.local/ns/dapr-system/dapr-sentry。
有关签名、过期等的基本 JWT 规则也适用。
jwks 验证器可以接受远程源来获取公钥列表或静态公钥数组。
下面的配置使用远程源启用 jwks 令牌验证器。
此远程源使用 HTTPS,因此 caCertificate 字段包含远程源的信任根。
kind: Configuration
apiVersion: dapr.io/v1alpha1
metadata:
name: sentryconfig
spec:
mtls:
enabled: true
tokenValidators:
- name: jwks
options:
minRefreshInterval: 2m
requestTimeout: 1m
source: "https://localhost:1234/"
caCertificate: "<optional ca certificate bundle string>"
下面的配置使用静态公钥数组启用 jwks 令牌验证器。
kind: Configuration
apiVersion: dapr.io/v1alpha1
metadata:
name: sentryconfig
spec:
mtls:
enabled: true
tokenValidators:
- name: jwks
options:
minRefreshInterval: 2m
requestTimeout: 1m
source: |
{"keys":[ "12345.." ]}
2 - 使用 OAuth 配置 endpoint 授权
Dapr OAuth 2.0 中间件 允许你使用 授权码授权流程 为你的 Web API 在 Dapr endpoint 上启用 OAuth 授权。 你也可以将授权令牌注入到你的 endpoint API 中,使用 客户端凭据授权流程 向你的 API 调用的外部 API 进行授权。 当中间件启用时,通过 Dapr 的任何方法调用都需要在传递给用户代码之前进行授权。
这两种流程的主要区别在于,授权码授权流程 需要用户交互并对用户进行授权,而 客户端凭据授权流程 不需要用户交互,对服务/应用程序进行授权。
在授权服务器上注册你的应用程序
不同的授权服务器提供不同的应用程序注册体验。以下是一些示例:
要配置 Dapr OAuth 中间件,你需要收集以下信息:
一些流行的授权服务器的授权/令牌 URL:
定义中间件组件定义
定义授权码授权组件
OAuth 中间件(授权码)由组件定义:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2
namespace: default
spec:
type: middleware.http.oauth2
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "<comma-separated scope names>"
- name: authURL
value: "<authorization URL>"
- name: tokenURL
value: "<token exchange URL>"
- name: redirectURL
value: "<redirect URL>"
- name: authHeaderName
value: "<header name under which the secret token is saved>"
# forceHTTPS:
# 此键用于在从身份提供者成功接收访问令牌后
# 在重定向到 API 方法时设置 HTTPS 架构。
# 默认情况下,Dapr 将在此重定向上使用 HTTP。
- name: forceHTTPS
value: "<set to true if you invoke an API method through Dapr from https origin>"
为授权码授权定义自定义管道
要使用 OAuth 中间件(授权码),你应该使用 Dapr 配置 创建一个自定义管道,如以下示例所示:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
httpPipeline:
handlers:
- name: oauth2
type: middleware.http.oauth2
定义客户端凭据授权组件
OAuth(客户端凭据)中间件由组件定义:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: myComponent
spec:
type: middleware.http.oauth2clientcredentials
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "<comma-separated scope names>"
- name: tokenURL
value: "<token issuing URL>"
- name: headerName
value: "<header name under which the secret token is saved>"
- name: endpointParamsQuery
value: "<list of additional key=value settings separated by ampersands or semicolons forwarded to the token issuing service>"
# authStyle:
# "0" 表示通过尝试两种方式并缓存
# 成功的方式来自动检测提供商想要哪种认证
# 方式。
# "1" 在 POST 正文中作为 application/x-www-form-urlencoded 参数
# 发送 "client_id" 和 "client_secret"。
# "2" 使用 HTTP Basic Authorization 发送 client_id 和 client_password。
# 这是 OAuth2 RFC 6749 第 2.3.1 节中描述的可选方式。
- name: authStyle
value: "<see comment>"
为客户端凭据授权定义自定义管道
要使用 OAuth 中间件(客户端凭据),你应该使用 Dapr 配置 创建一个自定义管道,如以下示例所示:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
httpPipeline:
handlers:
- name: myComponent
type: middleware.http.oauth2clientcredentials
应用配置
要将上述配置(无论授权类型如何)
应用到你的 Dapr sidecar,请在你的 pod spec 中添加 dapr.io/config 注解:
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
metadata:
...
annotations:
dapr.io/enabled: "true"
...
dapr.io/config: "pipeline"
...
访问访问令牌
授权码授权
一旦一切就绪,每当客户端尝试通过 Dapr sidecar 调用 API 方法 (例如调用 v1.0/invoke/ endpoint), 如果未找到访问令牌,它将被重定向到授权的同意页面。 否则,访问令牌将写入 authHeaderName header 并可供应用程序代码使用。
客户端凭据授权
一旦一切就绪,每当客户端尝试通过 Dapr sidecar 调用 API 方法 (例如调用 v1.0/invoke/ endpoint), 如果未找到有效的现有令牌,它将检索一个新的访问令牌。 访问令牌将写入 headerName header 并可供应用程序代码使用。 通过这种方式,应用程序可以在调用请求该令牌的外部 API 时,在授权 header 中转发该令牌。
3 - 在 Dapr 中启用 API 令牌身份验证
默认情况下,Dapr 依赖网络边界来限制对其公共 API 的访问。如果您计划将 Dapr API 暴露到该边界之外,或者您的部署需要额外的安全级别,请考虑为 Dapr API 启用令牌身份验证。这将导致 Dapr 要求每个传入的 gRPC 和 HTTP API 请求都包含身份验证令牌,然后才允许该请求通过。
创建令牌
Dapr 使用共享令牌进行 API 身份验证。您可以自由定义要使用的 API 令牌。
虽然 Dapr 对共享令牌的格式没有任何限制,但一个好的做法是生成一个随机字节序列并将其编码为 Base64。例如,以下命令生成一个随机的 32 字节密钥并将其编码为 Base64:
openssl rand 16 | base64
在 Dapr 中配置 API 令牌身份验证
令牌身份验证的配置在 Kubernetes 或自托管 Dapr 部署中略有不同:
自托管
在自托管场景中,Dapr 会检查是否存在 DAPR_API_TOKEN 环境变量。如果在 daprd 进程启动时设置了该环境变量,Dapr 将对其公共 API 强制执行身份验证:
export DAPR_API_TOKEN=<token>
要轮换已配置的令牌,请将 DAPR_API_TOKEN 环境变量更新为新值并重启 daprd 进程。
Kubernetes
在 Kubernetes 部署中,Dapr 利用 Kubernetes 密钥存储来保存共享令牌。要配置 Dapr API 身份验证,首先创建一个新密钥:
kubectl create secret generic dapr-api-token --from-literal=token=<token>
注意,上述密钥需要在您希望启用 Dapr 令牌身份验证的每个命名空间中创建。
要指示 Dapr 使用该密钥来保护其公共 API,请在您的 Deployment 模板规范中添加注解:
annotations:
dapr.io/enabled: "true"
dapr.io/api-token-secret: "dapr-api-token" # Kubernetes 密钥的名称
部署后,Dapr 边车注入器将自动创建密钥引用并将实际值注入到 DAPR_API_TOKEN 环境变量中。
向客户端 API 调用添加 API 令牌
在 Dapr 中配置了令牌身份验证后,所有调用 Dapr API 的客户端都需要在每个请求中附加 dapr-api-token 令牌。
注意: Dapr SDK 会读取 DAPR_API_TOKEN 环境变量并默认为您设置,但是您仍必须确保您的应用程序有权访问该环境变量。

HTTP
对于 HTTP,Dapr 要求在 dapr-api-token 标头中提供 API 令牌。例如:
GET http://<daprAddress>/v1.0/metadata
dapr-api-token: <token>
使用 curl,您可以使用 --header(或 -H)选项传递标头。例如:
curl http://localhost:3500/v1.0/metadata \
--header "dapr-api-token: my-token"
gRPC
使用 gRPC 协议时,Dapr 将在 gRPC 元数据中检查传入调用是否包含 API 令牌:
dapr-api-token[0].
从应用程序访问令牌
Kubernetes
在 Kubernetes 中,当您的应用程序向 Dapr API 发起出站调用(服务调用 invoke、发布订阅 publish 等)时,需要将 API 令牌作为环境变量挂载到应用程序 Pod 中,否则请求将失败并返回 Unauthorized 错误。挂载环境变量是通过在应用程序 Pod 规范中提供 Kubernetes 密钥的名称来完成的,如下例所示,其中使用名为 dapr-api-token 的 Kubernetes 密钥来保存令牌。
containers:
- name: mycontainer
image: myregistry/myapp
env:
- name: DAPR_API_TOKEN
valueFrom:
secretKeyRef:
name: dapr-api-token
key: token
自托管
在自托管模式下,您可以为应用程序将令牌设置为环境变量:
export DAPR_API_TOKEN=<my-dapr-token>
轮换令牌
自托管
要在自托管模式下轮换已配置的令牌,请将 DAPR_API_TOKEN 环境变量更新为新值并重启 daprd 进程。
Kubernetes
要在 Kubernetes 中轮换已配置的令牌,请使用新令牌更新先前在每个命名空间中创建的密钥。您可以使用 kubectl patch 命令执行此操作,但在每个命名空间中更新这些密钥的一种更简单方法是使用清单:
apiVersion: v1
kind: Secret
metadata:
name: dapr-api-token
type: Opaque
data:
token: <your-new-token>
然后将其应用到每个命名空间:
kubectl apply --file token-secret.yaml --namespace <namespace-name>
要告诉 Dapr 开始使用新令牌,请对每个部署触发滚动升级:
kubectl rollout restart deployment/<deployment-name> --namespace <namespace-name>
假设您的服务配置了多个副本,密钥轮换过程不会导致任何停机时间。
相关链接
4 - 使用令牌认证对来自 Dapr 的请求进行身份验证
对于某些构建块,例如发布订阅、服务调用和输入绑定,Dapr 通过 HTTP 或 gRPC 与应用程序通信。 为了使应用程序能够对来自 Dapr 边车的传入请求进行身份验证,您可以配置 Dapr 在调用应用程序时发送 API 令牌,作为标头(在 HTTP 请求中)或元数据(在 gRPC 请求中)。
创建令牌
Dapr 使用共享令牌进行 API 身份验证。您可以自由定义要使用的 API 令牌。
虽然 Dapr 不对共享令牌施加任何格式限制,但一个良好的做法是生成一个随机字节序列并将其编码为 Base64。例如,以下命令生成一个随机的 32 字节密钥并将其编码为 Base64:
openssl rand 16 | base64
在 Dapr 中配置应用 API 令牌认证
令牌身份验证配置在 Kubernetes 或自托管 Dapr 部署中略有不同:
自托管
在自托管场景中,Dapr 会查找 APP_API_TOKEN 环境变量。如果在 daprd 进程启动时设置了该环境变量,Dapr 会在调用应用程序时包含令牌:
export APP_API_TOKEN=<token>
要轮换配置的令牌,请将 APP_API_TOKEN 环境变量更新为新值并重启 daprd 进程。
Kubernetes
在 Kubernetes 部署中,Dapr 利用 Kubernetes secrets 存储来保存共享令牌。首先,创建一个新的 secret:
kubectl create secret generic app-api-token --from-literal=token=<token>
注意,上述 secret 需要在您希望启用应用令牌身份验证的每个命名空间中创建
要指示 Dapr 在向应用程序发送请求时使用 secret 中的令牌,请在您的 Deployment 模板规范中添加一个 annotation:
annotations:
dapr.io/enabled: "true"
dapr.io/app-token-secret: "app-api-token" # Kubernetes secret 的名称
部署后,Dapr Sidecar Injector 会自动创建 secret 引用并将实际值注入 APP_API_TOKEN 环境变量。
轮换令牌
自托管
要在自托管环境中轮换配置的令牌,请将 APP_API_TOKEN 环境变量更新为新值并重启 daprd 进程。
Kubernetes
要在 Kubernetes 中轮换配置的令牌,请使用新令牌更新每个命名空间中先前创建的 secret。您可以使用 kubectl patch 命令执行此操作,但在每个命名空间中更新这些 secret 的更简单方法是使用清单:
apiVersion: v1
kind: Secret
metadata:
name: app-api-token
type: Opaque
data:
token: <your-new-token>
然后将其应用到每个命名空间:
kubectl apply --file token-secret.yaml --namespace <namespace-name>
要告知 Dapr 开始使用新令牌,请触发每个部署的滚动升级:
kubectl rollout restart deployment/<deployment-name> --namespace <namespace-name>
假设您的服务配置了多个副本,密钥轮换过程不会导致任何停机时间。
对来自 Dapr 的请求进行身份验证
一旦使用环境变量或 Kubernetes secret app-api-token 配置了应用令牌身份验证,Dapr 边车在调用应用程序时始终包含 HTTP 标头/gRPC 元数据 dapr-api-token: <token>。在应用程序端,确保您使用 dapr-api-token 值进行身份验证,该值使用您设置的 app-api-token 来对来自 Dapr 的请求进行身份验证。

HTTP
在您的代码中,在传入请求中查找 HTTP 标头 dapr-api-token:
dapr-api-token: <token>
gRPC
使用 gRPC 协议时,检查传入调用中的 gRPC 元数据上的 API 令牌:
dapr-api-token[0].
从应用程序访问令牌
Kubernetes
在 Kubernetes 中,建议将 secret 作为环境变量挂载到您的 pod 中。
假设我们创建了一个名为 app-api-token 的 secret 来保存令牌:
containers:
- name: mycontainer
image: myregistry/myapp
envFrom:
- secretRef:
name: app-api-token
自托管
在自托管模式下,您可以为应用程序将令牌设置为环境变量:
export APP_API_TOKEN=<my-app-token>