You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB C驱动示例程序执行成功但退出时抛出endSessions未授权警告的问题咨询

MongoDB C驱动示例程序执行成功但退出时抛出endSessions未授权警告的问题咨询

我正在学习MongoDB C驱动的教程,运行了一个测试连接的示例程序(用来ping数据库),代码如下:

#include <mongoc/mongoc.h>
int main(void) {
    mongoc_client_t *client = NULL;
    bson_error_t error = {0};
    mongoc_server_api_t *api = NULL;
    mongoc_database_t *database = NULL;
    bson_t *command = NULL;
    bson_t reply = BSON_INITIALIZER;
    int rc = 0;
    bool ok = true;

    // Initialize the MongoDB C Driver.
    mongoc_init();

    client = mongoc_client_new("<connection string>");
    if (!client) {
        fprintf(stderr, "Failed to create a MongoDB client.\n");
        rc = 1;
        goto cleanup;
    }

    // Set the version of the Stable API on the client.
    api = mongoc_server_api_new(MONGOC_SERVER_API_V1);
    if (!api) {
        fprintf(stderr, "Failed to create a MongoDB server API.\n");
        rc = 1;
        goto cleanup;
    }

    ok = mongoc_client_set_server_api(client, api, &error);
    if (!ok) {
        fprintf(stderr, "error: %s\n", error.message);
        rc = 1;
        goto cleanup;
    }

    // Get a handle on the "admin" database.
    database = mongoc_client_get_database(client, "sample_restaurants"); // does not matter what database I use
    if (!database) {
        fprintf(stderr, "Failed to get a MongoDB database handle.\n");
        rc = 1;
        goto cleanup;
    }

    // Ping the database.
    command = BCON_NEW("ping", BCON_INT32(1));
    ok = mongoc_database_command_simple(
        database, command, NULL, &reply, &error
    );
    if (!ok) {
        fprintf(stderr, "error: %s\n", error.message);
        rc = 1;
        goto cleanup;
    }

    bson_destroy(&reply);
    printf("Pinged your deployment. You successfully connected to MongoDB!\n");

// Perform cleanup.
cleanup:
    bson_destroy(command);
    mongoc_database_destroy(database);
    mongoc_server_api_destroy(api);
    mongoc_client_destroy(client);
    mongoc_cleanup();

    return rc;
}

程序运行后能成功输出Pinged your deployment. You successfully connected to MongoDB!,但退出时会弹出警告:

2025/07/08 02:21:14.0310: [ 4981]: WARNING: client: Couldn't send "endSessions": (Unauthorized) not authorized on admin to execute command { endSessions: [[{id {4 [28 203 190 94 175 45 73 123 170 86 143 92 173 213 219 217]}}]], $db: "admin", $clusterTime: { clusterTime: {1751955674 24}, signature: { hash: {0 [63 11 33 56 229 121 251 43 192 100 254 6 0 186 230 195 215 177 133 49]}, keyId: 7461260273723113472.000000 } }, apiVersion: "1" }

明明核心功能正常,为什么退出时会出现这个权限警告?


问题原因分析

你的程序能成功ping通数据库,说明核心连接、认证逻辑是正常的。这个警告出现在程序退出的资源清理阶段:MongoDB C驱动在销毁mongoc_client_t对象时,会自动发送endSessions命令来关闭当前会话,但这个命令默认被发送到了admin数据库(从警告日志里的$db: "admin"可以确认)。

而你的连接账号大概率没有被授予admin数据库的endSessions权限,或者你在连接字符串中没有指定正确的认证源(authSource)——如果你的账号是在sample_restaurants(或其他非admin库)下创建的,驱动默认会去admin库查找该账号,自然会触发权限不足的警告。

解决方法

方法1:修改连接字符串指定认证源(推荐)

在你的连接字符串末尾添加authSource参数,指定你账号所在的数据库(比如你代码里用的sample_restaurants),示例:

mongodb://<username>:<password>@your-host:port/?authSource=sample_restaurants

这样驱动在执行认证和后续的endSessions命令时,都会使用你指定的数据库,而不是默认的admin库,就能彻底解决权限问题。

方法2:为账号授予admin库的endSessions权限(不推荐)

如果你确实需要保留默认的admin库作为认证源,可以给你的账号授予admin库的endSessions权限。在MongoDB Shell中执行以下命令:

use admin
// 授予最小必要权限:仅允许endSessions命令
db.grantPrivilegesToUser("<your-username>", [
  {
    resource: { db: "admin", collection: "" },
    actions: ["endSessions"]
  }
])

不过这种方法会让普通业务账号获得admin库的权限,不符合最小权限原则,因此更推荐方法1。

补充说明

这个警告不会影响程序的核心功能(比如数据库连接、数据读写),但会产生冗余的日志信息。如果你的应用对日志整洁度有要求,建议尽快修正。


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:43:03