OIDC(工作负载联合身份)
Overview
OpenID Connect (OIDC)身份验证机制允许您使用第三方身份提供商(例如Azure或Google Cloud Platform (GCP ))向MongoDB进行身份验证。
只有在对MongoDB Atlas或MongoDB Enterprise Advanced进行身份验证时,并且只能在对MongoDB v7.0 或更高版本进行身份验证时,才能使用此机制。
提示
OIDC 身份验证
要学习;了解有关为 OIDC身份验证配置MongoDB Atlas 的更多信息,请参阅Atlas文档中的 使用 OIDC 设置 Workforce Identity Federation。
有关在MongoDB中使用 OIDC身份验证的更多信息,请参阅MongoDB Server手册中的 OpenID Connect 身份验证和MongoDB Server参数。
代码占位符
本页上的代码示例使用以下占位符:
+srv
:仅当您连接到MongoDB Atlas 群集时,才在连接字符串前缀中包含此选项。 要学习;了解有关+srv
选项的更多信息,请参阅MongoDB Server手册中的连接字符串格式。<Azure ID>
:如果根据Azure IMDS 进行身份验证,则为Azure托管标识或企业应用程序的客户端ID或应用程序 ID 。<hostname>
: MongoDB 部署的网络解决。<port>
: MongoDB 部署的端口号。 如果省略此参数,驾驶员将使用默认端口号 (27017
)。 连接MongoDB Atlas 群集时无需指定端口。<audience>
:在MongoDB 部署上配置的audience
参数的值。
要使用本页上的代码示例,请将这些占位符替换为您自己的值。
重要
百分比编码
在将用户名和密码包含在MongoDB URI 中之前,必须对 用户名和密码进行百分号编码。quote_plus()
urllib.parse 模块中提供的 方法是执行此任务的一种方法。示例,调用 quote_plus("and / or")
会返回字符串 and+%2F+or
。
将用户名或密码作为参数传递给MongoClient
时,不要对用户名或密码进行百分号编码。
在应用程序中使用 OIDC 身份验证
以下部分介绍如何使用 MONGODB-OIDC 身份验证机制对各种平台进行身份验证。
注意
由于 Python 的标准库不支持异步HTTP请求,因此来自PyMongo的所有 OIDC 请求都是同步的,并会区块asyncio
循环。
Azure IMDS
如果应用程序在Azure VM 上运行,或以其他方式使用 Azure实例元数据服务(IMDS),您可以使用 PyMongo 的内置Azure支持对MongoDB进行身份验证。
您可以通过两种方式为Azure IMDS 配置 OIDC:将参数传递给 MongoClient
构造函数,或通过连接string中的参数。
注意
如果authMechanismProperties
值包含逗号,则必须使用MongoClient
构造函数来设立身份验证选项。
首先,为身份验证机制属性创建Python字典,如以下示例所示:
properties = {"ENVIRONMENT": "azure", "TOKEN_RESOURCE": "<audience>"}
然后,设置以下连接选项:
username
:如果使用的是 Azure 托管标识,请将其设置为托管标识的客户端 ID。 如果使用服务主体代表企业应用程序,请将其设置为服务主体的应用程序 ID。authMechanism
:设置为"MONGODB-OIDC"
。authMechanismProperties
:设置为您在上一步中创建的properties
字典。
以下代码示例展示了如何在创建MongoClient
时设立这些选项:
from pymongo import MongoClient # define properties and MongoClient properties = {"ENVIRONMENT": "azure", "TOKEN_RESOURCE": "<audience>"} client = MongoClient( "mongodb[+srv]://<hostname>:<port>", username="<Azure ID>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
在连接string中包含以下连接选项:
username
:如果使用的是 Azure 托管标识,请将其设置为托管标识的客户端 ID。 如果使用服务主体代表企业应用程序,请将其设置为服务主体的应用程序 ID。authMechanism
:设置为MONGODB-OIDC
。authMechanismProperties
:设置为ENVIRONMENT:azure,TOKEN_RESOURCE:<audience>
。以下代码示例展示了如何在连接string中设立这些选项:
from pymongo import MongoClient # define URI and MongoClient uri = ("mongodb[+srv]://<hostname>:<port>/?" "username=<username>" "&authMechanism=MONGODB-OIDC" "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>") client = MongoClient(uri)
提示
如果应用程序在 Azure VM 上运行,并且只有一个托管标识与该 VM 关联,则可以省略username
连接选项。
GCP IMDS
如果您的应用程序在 Google Compute Engine 虚拟机上运行,或以其他方式使用 GCP实例元数据服务 ,您可以使用 PyMongo 的内置GCP支持对MongoDB进行身份验证。
您可以通过两种方式为GCP IMDS 配置 OIDC:将参数传递给 MongoClient
构造函数,或通过连接string中的参数。
注意
如果authMechanismProperties
值包含逗号,则必须使用MongoClient
构造函数来设立身份验证选项。
首先,为身份验证机制属性创建Python字典,如以下示例所示。
properties = {"ENVIRONMENT": "gcp", "TOKEN_RESOURCE": "<audience>"}
然后,设置以下连接选项:
authMechanism
:设置为"MONGODB-OIDC"
。authMechanismProperties
:设置为您在上一步中创建的properties
字典。
以下代码示例展示了如何在创建MongoClient
时设立这些选项:
from pymongo import MongoClient # define properties and MongoClient properties = {"ENVIRONMENT": "gcp", "TOKEN_RESOURCE": "<audience>"} client = MongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
在连接string中包含以下连接选项:
authMechanism
:设置为MONGODB-OIDC
。authMechanismProperties
:设置为ENVIRONMENT:gcp,TOKEN_RESOURCE:<audience>
。
以下代码示例展示了如何在连接string中设立这些选项:
from pymongo import MongoClient # define URI and MongoClient uri = ("mongodb[+srv]://<hostname>:<port>/?" "&authMechanism=MONGODB-OIDC" "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>") client = MongoClient(uri)
其他 Azure 环境
如果应用程序在Azure Functions、App Service 环境 (ASE) 或Azure Kubernetes服务 (AKS) 上运行,则可以使用 azure-identity 包以获取身份验证凭证。
首先,使用 pip 安装azure-identity
库,如以下示例所示:
python3 -m pip install azure-identity
接下来,定义一个从OIDCCallback
类继承的类。 此类必须实现fetch()
方法,该方法以OIDCCallbackResult
对象的形式返回 OIDC 令牌。
以下示例演示如何定义名为MyCallback
的回调类。 此类包括一个fetch()
方法,该方法从标准服务帐户令牌文件位置的文件中检索 OIDC 令牌。
audience = "<audience>" client_id = "<Azure ID>" class MyCallback(OIDCCallback): def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult: credential = DefaultAzureCredential(managed_identity_client_id=client_id) token = credential.get_token(f"{audience}/.default").token return OIDCCallbackResult(access_token=token)
定义回调类后,创建一个 Python 字典,其中包含一个键"OIDC_CALLBACK"
,其值是自定义回调类的一个实例:
properties = {"OIDC_CALLBACK": MyCallback()}
最后,通过将以下参数传递给 MongoClient
构造函数设立以下连接选项:
authMechanism
:设置为"MONGODB-OIDC"
。authMechanismProperties
:设置为您在上一步中创建的properties
字典。
选择 Synchronous 或 Asynchronous标签页以查看相应的代码:
client = MongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
client = AsyncMongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
GCP GKE
如果您的应用程序在GCP Google Kubernetes Engine (GKE)集群上运行并 配置了服务帐号 ,您可以从 标准 服务账户令牌文件位置读取 OIDC 令牌。
首先,定义一个从OIDCCallback
类继承的类。 此类必须实现fetch()
方法,该方法以OIDCCallbackResult
对象的形式返回 OIDC 令牌。
以下示例演示如何定义名为MyCallback
的回调类。 此类包括一个fetch()
方法,该方法从标准服务帐户令牌文件位置的文件中检索 OIDC 令牌。
class MyCallback(OIDCCallback): def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult: with open("/var/run/secrets/kubernetes.io/serviceaccount/token") as fid: token = fid.read() return OIDCCallbackResult(access_token=token)
定义回调类后,创建一个 Python 字典,其中包含一个键"OIDC_CALLBACK"
,其值是自定义回调类的一个实例:
properties = {"OIDC_CALLBACK": MyCallback()}
最后,通过将以下参数传递给 MongoClient
构造函数设立以下连接选项:
authMechanism
:设置为"MONGODB-OIDC"
。authMechanismProperties
:设置为您在上一步中创建的properties
字典。
选择 Synchronous 或 Asynchronous标签页,查看相应的代码:
client = MongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
client = AsyncMongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
Kubernetes
如果应用程序在Kubernetes集群上运行,则可以使用 PyMongo 的内置Kubernetes支持对MongoDB进行身份验证。
您可以通过两种方式为Kubernetes配置 OIDC:将参数传递给 MongoClient
构造函数,或通过连接字符串中的参数。 从以下标签页中进行选择,查看如何为应用程序启用Kubernetes身份验证:
properties = {"ENVIRONMENT": "k8s"} client = MongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
uri = ("mongodb[+srv]://<hostname>:<port>/?" "authMechanism=MONGODB-OIDC" "&authMechanismProperties=ENVIRONMENT:k8s") client = MongoClient(uri)
properties = {"ENVIRONMENT": "k8s"} client = AsyncMongoClient( "mongodb[+srv]://<hostname>:<port>", authMechanism="MONGODB-OIDC", authMechanismProperties=properties )
uri = ("mongodb[+srv]://<hostname>:<port>/?" "authMechanism=MONGODB-OIDC" "&authMechanismProperties=ENVIRONMENT:k8s") client = AsyncMongoClient(uri)