企业身份验证机制
概述
在本指南中,您可以学习如何使用MongoDB企业版中唯一可用的每种身份验证机制进行身份验证。
您可以使用以下机制与MongoDB企业版最新版本一起使用
指定身份验证机制
您可以通过以下任一方式连接到MongoDB并指定您的身份验证机制和凭据
连接字符串
A
MongoCredential工厂方法
连接字符串(也称为连接URI)指定了如何连接和身份验证到您的MongoDB集群。
要使用连接字符串进行身份验证,请将设置包含在您的连接字符串中,并将其传递给 MongoClients.create() 方法以实例化您的 MongoClient。选择连接字符串 选项卡,查看使用连接字符串进行身份验证的语法。
或者,您可以使用 MongoCredential 类来指定您的身份验证详情。该 MongoCredential 类包含静态工厂方法,用于构建包含您的身份验证机制和凭据的实例。当您使用 MongoCredential 辅助类时,您需要使用 MongoClientSettings.Builder 类来配置您的连接设置,当构建您的 MongoClient 时。选择 MongoCredential 选项卡,查看使用 MongoCredential 进行身份验证的语法。
有关这些类和方法的更多信息,请参阅以下API文档
机制
Kerberos (GSSAPI)
通用安全服务API(GSSAPI)认证机制允许用户使用用户的主名来认证Kerberos服务。
注意
该方法指的是GSSAPI认证机制而不是Kerberos,因为驱动程序使用GSSAPI RFC-4652 SASL机制。
以下代码片段显示了如何指定认证机制,使用以下占位符
username:你的URL编码的主名,例如"username%40REALM.ME"hostname:你的客户端可以访问的MongoDB部署的网络地址port:你的MongoDB部署的端口号
选择下面的连接字符串或MongoCredential选项卡以获取指定此认证机制的说明和示例代码
使用连接字符串指定GSSAPI认证机制
将
authMechanismURL 参数赋值为GSSAPI(可选) 将
authSourceURL 参数赋值为$external
注意
如果您指定了 GSSAPI 机制,则不能将 authSource 赋值为除 $external 之外的其他值。
创建 MongoClient 的代码如下所示
MongoClient mongoClient = MongoClients.create("<db_username>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI");
要使用 MongoCredential 类指定 GSSAPI 身份验证机制,请使用 createGSSAPICredential() 方法。创建 MongoClient 的代码如下所示
MongoCredential credential = MongoCredential.createGSSAPICredential(<db_username>); MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("<hostname>", <port>)))) .credential(credential) .build());
为了获取 Kerberos 凭证,GSSAPI Java 库要求您指定领域和密钥分发中心 (KDC) 系统属性。以下示例中展示了示例设置
java.security.krb5.realm=MYREALM.ME java.security.krb5.kdc=mykdc.myrealm.me
根据您的 Kerberos 配置,您可能需要指定以下一个或多个额外的 MongoCredential 机制属性
服务名称规范主机名Java 主体Java SASL 客户端属性Java 主体提供者
重要
您只能使用 MongoCredential 指定以下 GSSAPI 属性
Java 主体Java SASL 客户端属性Java 主体提供者
选择 MongoCredential 选项卡,查看如何指定它们。
要指定 GSSAPI 的附加属性之一,请将其包含在连接字符串中,格式为:<属性名>:<值>。
使用 GSSAPI 和附加属性实例化 MongoClient 的代码可能如下所示
MongoClient mongoClient = MongoClients.create("<db_username>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:myService");
要指定 GSSAPI 的附加属性之一,请调用您的 MongoCredential 实例上的 withMechanismProperty() 方法,并传递属性名和值作为参数。请使用在 MongoCredential 类中定义的属性名常量
选择 服务名称键 或 Java 主体键 选项卡,查看如何使用 GSSAPI 和所选属性实例化 MongoCredential 的示例代码
MongoCredential credential = MongoCredential.createGSSAPICredential(<db_username>); credential = credential.withMechanismProperty(MongoCredential.SERVICE_NAME_KEY, "myService");
LoginContext loginContext = new LoginContext(<LoginModule implementation from JAAS config>); loginContext.login(); Subject subject = loginContext.getSubject(); MongoCredential credential = MongoCredential.createGSSAPICredential(<db_username>); credential = credential.withMechanismProperty(MongoCredential.JAVA_SUBJECT_KEY, subject);
默认情况下,Java 驱动程序通过 MongoClient 实例缓存 Kerberos 凭证。如果您的部署需要频繁创建和销毁 MongoClient 实例,您可以更改默认的 Kerberos 凭证缓存行为,以按进程缓存以提高性能。
要按进程缓存Kerberos票据,您必须使用MongoCredential身份验证机制,因为连接字符串身份验证机制不支持JAVA_SUBJECT_PROVIDER机制属性。如果您想按进程缓存Kerberos票据,请选择MongoCredential选项卡了解如何实现此功能。
要按进程缓存Kerberos票据,您必须指定JAVA_SUBJECT_PROVIDER机制属性,并在您的MongoCredential实例中提供KerberosSubjectProvider。配置Java驱动以按进程缓存Kerberos票据的代码类似于以下内容
/* all MongoClient instances sharing this instance of KerberosSubjectProvider will share a Kerberos ticket cache */ String myLoginContext = "myContext"; MongoCredential credential = MongoCredential.createGSSAPICredential(<db_username>); /* login context defaults to "com.sun.security.jgss.krb5.initiate" if unspecified in KerberosSubjectProvider */ credential = credential.withMechanismProperty(MongoCredential.JAVA_SUBJECT_PROVIDER_KEY, new KerberosSubjectProvider(myLoginContext));
注意
在Windows上,Oracle的JRE使用LSA而不是SSPI来实现GSSAPI,这限制了与Windows活动目录和单点登录实现的互操作性。有关更多信息,请参阅以下文章
LDAP (PLAIN)
自MongoDB企业版3.4及以后版本中提供。
您可以使用目录服务器的用户名和密码对轻量级目录访问协议(LDAP)服务器进行身份验证。
提示
认证机制命名为 PLAIN 而不是 LDAP,因为它使用 RFC-4616 中定义的 PLAIN 简单身份验证和安全层 (SASL)。
您可以通过将 authMechanism 参数设置为 PLAIN 并在 连接字符串 中包含您的 LDAP 用户名和密码来指定此认证机制。
以下代码片段显示了如何指定认证机制,使用以下占位符
username: 您的 LDAP 用户名password: 您的 LDAP 用户的密码hostname:你的客户端可以访问的MongoDB部署的网络地址port:你的MongoDB部署的端口号
选择下面的连接字符串或MongoCredential选项卡以获取指定此认证机制的说明和示例代码
使用连接字符串指定 LDAP (PLAIN) 认证机制
将
authMechanismURL 参数设置为PLAIN(可选) 将
authSourceURL 参数赋值为$external
注意
如果您指定了 PLAIN 机制,则不能将 authSource 设置为除 $external 之外的其他值。
创建 MongoClient 的代码如下所示
MongoClient mongoClient = MongoClients.create("<db_username>:<db_password>@<hostname>:<port>/?authSource=$external&authMechanism=PLAIN");
要使用 MongoCredential 类指定 LDAP (PLAIN) 认证机制,请使用 createPlainCredential() 方法。创建 MongoClient 的代码类似于以下内容
MongoCredential credential = MongoCredential.createPlainCredential(<db_username>, "$external", <db_password>); MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("<hostname>", <port>)))) .credential(credential) .build());
MONGODB-OIDC
重要
MONGODB-OIDC 认证机制需要 MongoDB Server v7.0 或更高版本在 Linux 平台上运行。
以下各节描述了如何使用 MONGODB-OIDC 认证机制在各种平台上进行身份验证。
有关 MONGODB-OIDC 认证机制的更多信息,请参阅 MongoDB 服务器手册中的 OpenID Connect 认证 和 MongoDB 服务器参数。
Azure IMDS
如果您的应用程序运行在Azure虚拟机上,或者使用了Azure实例元数据服务(IMDS),您可以使用Java驱动程序的内置Azure支持通过MongoDB进行认证。
您可以通过使用MongoCredential或将其作为连接字符串的一部分来指定Azure IMDS OIDC认证。
选择“连接字符串”或“MongoCredential”选项卡以查看相应的语法。
将以下代码中的<percent-encoded audience>占位符替换为在您的MongoDB部署上配置的受众服务器参数的百分编码值。
逗号(,)字符及其编码(%2C)是保留的,在值中使用这些字符会导致驱动程序将这些逗号解释为键值对的分隔符。您必须在MongoCredential实例中指定包含逗号的值,如“MongoCredential”选项卡中所示。
MongoClient mongoClient = MongoClients.create( "mongodb://<db_username>@<hostname>:<port>/?" + "?authMechanism=MONGODB-OIDC" + "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>");
将<db_username>占位符替换为Azure托管标识或企业应用程序的客户ID或应用程序ID。将<audience>占位符替换为您的MongoDB部署上配置的audience服务器参数的值。
MongoCredential credential = MongoCredential.createOidcCredential("<db_username>") .withMechanismProperty("ENVIRONMENT", "azure") .withMechanismProperty("TOKEN_RESOURCE", "<audience>"); MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("<hostname>", <port>)))) .credential(credential) .build());
Google Cloud Platform (GCP) 实例元数据服务
如果您的应用程序在 Google Compute Engine 虚拟机上运行,或者使用GCP 实例元数据服务,您可以使用 Java 驱动的内置 GCP 支持通过 Java 驱动器进行 MongoDB 身份验证。
您可以通过使用 MongoCredential 或将其作为连接字符串的一部分来指定 GCP IMDS OIDC 身份验证。
选择“连接字符串”或“MongoCredential”选项卡以查看相应的语法。
将以下代码中的<percent-encoded audience>占位符替换为在您的MongoDB部署上配置的受众服务器参数的百分编码值。
逗号(,)字符及其编码(%2C)是保留的,在值中使用这些字符会导致驱动程序将这些逗号解释为键值对的分隔符。您必须在MongoCredential实例中指定包含逗号的值,如“MongoCredential”选项卡中所示。
MongoClient mongoClient = MongoClients.create( "mongodb://<hostname>:<port>/?" + "authMechanism=MONGODB-OIDC" + "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>");
将 <audience> 占位符替换为您在 MongoDB 部署上配置的 audience 服务器参数的值。
MongoCredential credential = MongoCredential.createOidcCredential() .withMechanismProperty("ENVIRONMENT", "gcp") .withMechanismProperty("TOKEN_RESOURCE", "<audience>"); MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("<hostname>", <port>)))) .credential(credential) .build());
自定义回调
Java 驱动器不提供对所有平台的原生支持,包括 Azure Functions 和 Azure Kubernetes Service (AKS)。相反,您必须定义一个自定义回调来使用 OIDC 从这些平台进行身份验证。为此,请使用以下代码示例中的 "OIDC_CALLBACK" 身份验证属性。
MongoCredential credential = MongoCredential.createOidcCredential(null) .withMechanismProperty("OIDC_CALLBACK", (context) -> { String accessToken = ... return new OidcCallbackResult(accessToken); });
“OIDC_CALLBACK”属性的值必须是一个lambda或其他实现OidcCallback函数接口的对象,该接口接受一个OidcCallbackContext作为参数,并返回一个OidcCallbackResult。
以下示例使用一个示例回调来从本地文件系统中名为"access-token.dat"的文件中检索OIDC令牌
MongoCredential credential = MongoCredential.createOidcCredential(null) .withMechanismProperty("OIDC_CALLBACK", (context) -> { string accessToken = new String(Files.readAllBytes(Paths.get("access-token.dat")); return new OidcCallbackResult(accessToken); }); MongoClient mongoClient = MongoClients.create( MongoClientSettings.builder() .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("<hostname>", <port>)))) .credential(credential) .build());