陈大老爷 發表於 2020-8-12 21:55:00

MongoDB 4.2 用户管理

<h1>背景</h1>
<p><span style="font-size: 16px">最近在扫盲MongoDB 4.2 的相关知识点,顺便记录下日常的一些操作。包括:用户管理、索引管理、引擎管理、副本集管理、分片管理等。本文对MongoDB的用户管理进行说明,以前有针对MogoDB 3.0的用户管理进行过说明:MongoDB 3.0 用户创建</span></p>
<p><span style="font-size: 16px">本文MongoDB的配置文件模板:</span></p>
<div class="cnblogs_code"><img src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" id="code_img_closed_cda56275-6553-4e02-9141-14c6bb3d7c41" class="code_img_closed"><img src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" id="code_img_opened_cda56275-6553-4e02-9141-14c6bb3d7c41" class="code_img_opened" style="display: none">
<div id="cnblogs_code_open_cda56275-6553-4e02-9141-14c6bb3d7c41" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">systemLog:
   verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
   quiet: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
   traceAllExceptions: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
   syslogFacility: user
   path: </span>/data/mongodb/logs/<span style="color: rgba(0, 0, 0, 1)">mongodb.log
   logAppend: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
   logRotate: rename
   destination: file
   timeStampFormat: iso8601</span>-<span style="color: rgba(0, 0, 0, 1)">local
   component:
      accessControl:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      command:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      control:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      ftdc:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      geo:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      index:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      network:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      query:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      replication:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
         election:
            verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
         heartbeats:
            verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
         initialSync:
            verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
         rollback:
            verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      sharding:
          verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      storage:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
         journal:
            verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
         recovery:
            verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      transaction:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">
      write:
         verbosity: </span>0<span style="color: rgba(0, 0, 0, 1)">

processManagement:
   fork: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
   pidFilePath: </span>/data/mongodb/data/<span style="color: rgba(0, 0, 0, 1)">mongodb.pid
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">   timeZoneInfo: &lt;string&gt;</span>
<span style="color: rgba(0, 0, 0, 1)">
net:
   port: </span>27017<span style="color: rgba(0, 0, 0, 1)">
   bindIp: </span>0.0.0.0<span style="color: rgba(0, 0, 0, 1)">
   maxIncomingConnections: </span>65536<span style="color: rgba(0, 0, 0, 1)">
   wireObjectCheck: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
   ipv6: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
   unixDomainSocket:
      enabled: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
      pathPrefix: </span>/<span style="color: rgba(0, 0, 0, 1)">tmp
      filePermissions: </span>0700<span style="color: rgba(0, 0, 0, 1)">
   tls:
      mode: disabled
   compression:
      compressors: snappy,zstd,zlib
   serviceExecutor: synchronous

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">security:</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   keyFile: &lt;string&gt;</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   clusterAuthMode: keyFile</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   authorization: enabled</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   transitionToAuth: false</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   javascriptEnabled: true</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   redactClientLogData: &lt;boolean&gt;</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   clusterIpSourceWhitelist:</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   - 127.0.0.1</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">   - ::1</span>
<span style="color: rgba(0, 0, 0, 1)">
storage:
   dbPath: </span>/data/mongodb/data/<span style="color: rgba(0, 0, 0, 1)">
   indexBuildRetry: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
   journal:
      enabled: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
      commitIntervalMs: </span>500<span style="color: rgba(0, 0, 0, 1)">
   directoryPerDB: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
   syncPeriodSecs: </span>60<span style="color: rgba(0, 0, 0, 1)">
   engine: wiredTiger
   wiredTiger:
      engineConfig:
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">         cacheSizeGB: &lt;number&gt;</span>
<span style="color: rgba(0, 0, 0, 1)">         journalCompressor: snappy
         directoryForIndexes: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
operationProfiling:
   </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 指定应分析哪些操作,默认off:分析器已关闭,并且不收集任何数据;slowOp:收集比slowms的时间长的数据;all:收集所有操作的数据</span>
<span style="color: rgba(0, 0, 0, 1)">   mode: slowOp
   slowOpThresholdMs: </span>100<span style="color: rgba(0, 0, 0, 1)">
   slowOpSampleRate: </span>1<span style="color: rgba(0, 0, 0, 1)">

replication:
   </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 复制日志(oplog)的最大大小(以M为单位),仅适用于mongod。操作日志通常是可用磁盘空间的5%,更改正在运行的副本集成员的操作日志大小,请使用replSetResizeOplog管理命令。</span>
   oplogSizeMB: 100
   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> replSetName: &lt;string&gt;</span>

<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">sharding:</span>
   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 分片群集中扮演的角色,可选值configsvr:配置服务器,端口27019开始;shardsvr:分片,端口27018开始;需要将实例部署为副本集成员,使用replSetName设置并指定副本集的名称,仅适用于mongod。</span>
   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> clusterRole: &lt;string&gt;</span>
   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> configDB: &lt;string&gt;</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<h2>用户管理</h2>
<p><span style="font-size: 16px">在一个新的实例上,创建的第一个用户应该是具有管理其他用户权限的用户管理员。在MongoDB部署上启用访问控制会强制执行身份验证,要求用户认证自己,用户只能执行根据其角色确定的操作。具体的用户管理可以看<code class="descclassname"></code><span class="sig-paren">官方文档</span>或则MongoDB用户创建,本文做下补充。<br></span></p>
<p><span style="font-size: 16px">1,创建用户:<code class="descclassname">db.</code><code class="descname">createUser</code><span class="sig-paren">(user,&nbsp;writeConcern<span class="sig-paren">)</span></span><br></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"><strong>user</strong></span><span style="color: rgba(0, 0, 0, 1)">:包含有关要创建的用户的身份验证和访问信息。
<strong>writeConcern</strong>:可选,创建操作的写关注级别。 writeConcern文档的字段与getLastError命令的字段相同。</span></pre>
</div>
<p><span style="font-size: 16px">MongoDB4.2开始,可以使用passwordPrompt()方法来提示输入密码,不需要在命令中指定密码。但仍然可以像使用早期版本的MongoDB一样直接指定密码。</span><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 0, 0, 1)"><strong>user</strong></span>: "<span style="color: rgba(128, 128, 128, 1)">&lt;</span>name<span style="color: rgba(128, 128, 128, 1)">&gt;</span>",   <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)"> 用户名</span>
<strong>pwd</strong>: passwordPrompt(),    <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)"> 提示输入密码,也可以直接写密码</span>
customData: { <span style="color: rgba(128, 128, 128, 1)">&lt;any</span> information<span style="color: rgba(128, 128, 128, 1)">&gt;</span> },<span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)"> 可选,可用于存储与此特定用户关联的任何数据。 例如,这可以是用户的全名或员工ID。</span>
<strong>roles</strong>: <span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)">
    { role: "&lt;role&gt;", db: "&lt;database&gt;" } | "&lt;role&gt;",
    ...
</span><span style="color: rgba(255, 0, 0, 1)">]</span>,   <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)"> 授予用户的角色。 可以指定一个空数组[]来创建没有角色的用户</span>
authenticationRestrictions: <span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)">
   {
       clientSource: ["&lt;IP&gt;" | "&lt;CIDR range&gt;", ...</span><span style="color: rgba(255, 0, 0, 1)">]</span><span style="color: rgba(0, 0, 0, 1)">,
       serverAddress: </span><span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)">"&lt;IP&gt;" | "&lt;CIDR range&gt;", ...</span><span style="color: rgba(255, 0, 0, 1)">]</span><span style="color: rgba(0, 0, 0, 1)">
   },
   ...
],</span><span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)"> 可选,服务器对创建的用户强制执行的身份验证限制,指定允许用户连接到服务器或服务器可以接受用户的IP地址和CIDR(无类别域间路由)范围的列表</span>
mechanisms: <span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)"> "&lt;SCRAM-SHA-1|SCRAM-SHA-256&gt;", ... </span><span style="color: rgba(255, 0, 0, 1)">]</span>,<span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">可选,指定特定的SCRAM机制或用于创建SCRAM用户凭据的机制</span>
passwordDigestor: "<span style="color: rgba(128, 128, 128, 1)">&lt;</span>server<span style="color: rgba(128, 128, 128, 1)">|</span>client<span style="color: rgba(128, 128, 128, 1)">&gt;</span>"<span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">可选,指服务器还是客户端提取密码。</span>
}</pre>
</div>
<p><span style="font-size: 16px">其中在roles字段中,可以指定内置角色和用户定义的角色:<br></span></p>
<div class="cnblogs_code">
<pre>Built<span style="color: rgba(128, 128, 128, 1)">-In</span><span style="color: rgba(0, 0, 0, 1)"> Roles(内置角色):
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">1</span>. 数据库用户角色:<span style="color: rgba(0, 0, 255, 1)">read</span><span style="color: rgba(0, 0, 0, 1)">、readWrite;
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">2</span><span style="color: rgba(0, 0, 0, 1)">. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">3</span><span style="color: rgba(0, 0, 0, 1)">. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">4</span>. 备份恢复角色:<span style="color: rgba(0, 0, 255, 1)">backup</span>、<span style="color: rgba(0, 0, 255, 1)">restore</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">5</span><span style="color: rgba(0, 0, 0, 1)">. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">6</span><span style="color: rgba(0, 0, 0, 1)">. 超级用户角色:root
    </span><span style="color: rgba(128, 128, 128, 1)">//</span><span style="color: rgba(0, 0, 0, 1)"> 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
    </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">7</span>. 内部角色:__system</pre>
</div>
<p><span style="font-size: 16px">具体权限:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">read</span><span style="color: rgba(0, 0, 0, 1)">:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限</span></pre>
</div>
<p><strong><span style="font-size: 16px">创建用户:</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">db.createUser(
{
<strong>user</strong>:'dba',
<strong>pwd</strong>:passwordPrompt(),
<strong>roles</strong>:[{role:'root',db:'admin'}],
<strong>customData</strong>:{name:'运维账号'},
<strong>authenticationRestrictions</strong>: [ {
      clientSource: ["192.168.163.134"],
      serverAddress: ["192.168.163.134"]
   } ]
}
)</span></pre>
</div>
<p><span style="font-size: 16px">说明<strong>:</strong>创建一个用户名为dba的管理角色(root)的账号,且备注为运维账号,并只能在IP为192.168.163.134的主机上访问。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> xxx
db.createUser(
{
</span><span style="color: rgba(0, 0, 0, 1)"><strong>user</strong>:'zjy',
<strong>pwd</strong>:passwordPrompt(),
<strong>roles</strong>:[{role:'<strong>readAnyDatabase</strong>',db:'admin'},
"<strong>readWrite</strong>"
],
<strong>customData</strong>:{name:'运维账号'},
<strong>authenticationRestrictions</strong>: [ {
      clientSource: ["192.168.163.134"],
      serverAddress: ["192.168.163.134"]</span><span style="color: rgba(0, 0, 0, 1)">
   } ]
},
{ <strong>w</strong>: "majority" , <strong>wtimeout</strong>: </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">5000</span><span style="color: rgba(0, 0, 0, 1)"> }
)</span></pre>
</div>
<p><span style="font-size: 16px">说明<strong>:</strong>创建一个用户名为zjy的账号,对当前库(xxx)有readWrite权限,对指定库(admin)有readAnyDatabase权限;且备注为运维账号,并只能在IP为192.168.163.134的主机上访问。</span></p>
<p><span style="font-size: 16px">关于账号权限的一些说明可以看MongoDB用户创建。</span></p>
<p><span style="font-size: 16px">2,修改用户密码:</span><span style="font-size: 16px">db.changeUserPassword(username,password)</span></p>
<div class="cnblogs_code">
<pre>db.changeUserPassword(<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">user</span><span style="color: rgba(255, 0, 0, 1)">'</span>,<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">pwd</span><span style="color: rgba(255, 0, 0, 1)">'</span>)</pre>
</div>
<p><span style="font-size: 16px">3,查看指定用户:db.getUser(username, args)<br></span></p>
<p><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre>db.getUser( "<span style="color: rgba(128, 128, 128, 1)">&lt;</span>username<span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">", {
   showCredentials: </span><span style="color: rgba(128, 128, 128, 1)">&lt;</span>Boolean<span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">,
   showPrivileges: </span><span style="color: rgba(128, 128, 128, 1)">&lt;</span>Boolean<span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">,
   showAuthenticationRestrictions: </span><span style="color: rgba(128, 128, 128, 1)">&lt;</span>Boolean<span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">,
   filter: </span><span style="color: rgba(128, 128, 128, 1)">&lt;</span>document<span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
} )</span></pre>
</div>
<p><span style="font-size: 16px">其中"&lt;username&gt;"表示数据库用户,其他的参数都是可选项:</span></p>
<ul>
<li><span style="font-size: 16px">showCredentials:查看用户证书</span></li>
<li><span style="font-size: 16px">showPrivileges:查看用户权限</span></li>
<li><span style="font-size: 16px">showAuthenticationRestrictions:查看用户限制条件<br></span></li>















</ul>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span> db.getUser(<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">dba</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 0, 1)">{
    "_id" : "admin.dba",
    "userId" : UUID("6a1c2217-0c5b-4aa6-a29b-de50ac1d84ae"),
    "user" : "dba",
    "db" : "admin",
    "customData" : {
      "name" : "运维账号abc"
    },
    "roles" : [
      {
            "role" : "root",
            "db" : "admin"
      }
    ],
    "mechanisms" : [
      "SCRAM-SHA-1",
      "SCRAM-SHA-256"
    ]
}

&gt; db.getUser('dba',{showPrivileges:<span style="font-weight: bold">1</span>})
...
...</span></pre>
</div>
<p><span style="font-size: 16px">4,查看当前库的所有用户:db.getUsers(&lt;options&gt;)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)"> db.getUsers() <span style="color: rgba(255, 0, 0, 1)">==</span> <strong>show users
</strong></span><span style="color: rgba(0, 0, 0, 1)">[
    {
      "_id" : "xxx.zjy",
      "userId" : UUID("2ad9f4c9-e156-4e71-b8f9-3915beb322e8"),
      "user" : "zjy",
      "db" : "xxx",
      "customData" : {
            "name" : "运维账号"
      },
      "roles" : [
            {
                "role" : "readAnyDatabase",
                "db" : "admin"
            },
            {
                "role" : "readWrite",
                "db" : "xxx"
            }
      ],
      "mechanisms" : [
            "SCRAM-SHA-1",
            "SCRAM-SHA-256"
      ]
    }
]</span></pre>
</div>
<p><span style="font-size: 16px">5,移除、删除指定用户:db.removeUser(username)、db.dropUser(username, writeConcern)<br></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span> db.removeUser(<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">zjy</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
WARNING: db.removeUser has been deprecated, please </span><span style="color: rgba(0, 0, 255, 1)">use</span> db.dropUser instead<span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">不推荐使用</span>
<span style="color: rgba(0, 0, 0, 1)">true

</span><span style="color: rgba(128, 128, 128, 1)">&gt;</span> db.dropUser(<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">accountAdmin01</span><span style="color: rgba(255, 0, 0, 1)">'</span>,{w: "majority", wtimeout: <span style="color: rgba(128, 0, 0, 1); font-weight: bold">5000</span><span style="color: rgba(0, 0, 0, 1)">})
true</span></pre>
</div>
<p><span style="font-size: 16px">如果在副本集上运行,则默认情况下使用多数写关注来执行db.dropUser()。</span></p>
<p><span style="font-size: 16px">6,删除当前库所有用户:db.dropAllUsers(writeConcern)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span> db.dropAllUsers({w: "majority", wtimeout: <span style="color: rgba(128, 0, 0, 1); font-weight: bold">5000</span><span style="color: rgba(0, 0, 0, 1)">})
NumberLong(</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">4</span>)</pre>
</div>
<p><span style="font-size: 16px">7,更新指定用户:db.updateUser(username, update, writeConcern)</span></p>
<p><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">db.updateUser(
   "&lt;username&gt;",
   {
   customData : { &lt;any information&gt; },
   roles : [
       { role: "&lt;role&gt;", db: "&lt;database&gt;" } | "&lt;role&gt;",
       ...
   ],
   pwd: passwordPrompt(),      // Or"&lt;cleartext password&gt;"
   authenticationRestrictions: [
      {
          clientSource: ["&lt;IP&gt;" | "&lt;CIDR range&gt;", ...],
          serverAddress: ["&lt;IP&gt;", | "&lt;CIDR range&gt;", ...]
      },
      ...
   ],
   mechanisms: [ "&lt;SCRAM-SHA-1|SCRAM-SHA-256&gt;", ... ],
   passwordDigestor: "&lt;server|client&gt;"
   },
   writeConcern: { &lt;write concern&gt; }
)</span></pre>
</div>
<p><span style="font-size: 16px">上面各个参数的意思和createUser一致。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; db.updateUser(
... 'user123',
... {
... pwd:passwordPrompt(),
... roles:['read'],
... customData:{name:'运维账号'},
... authenticationRestrictions: [ {
...         clientSource: ["192.168.163.134"],
...         serverAddress: ["192.168.163.134"]
...      } ]
... },
... { w: "majority" , wtimeout: <span style="font-weight: bold">5000</span> }
... )</span></pre>
</div>
<p><span style="font-size: 16px">8,授权role给指定用户:db.grantRolesToUser(username, roles, writeConcern)</span></p>
<p><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre>db.grantRolesToUser( "<span style="color: rgba(128, 128, 128, 1)">&lt;</span>username<span style="color: rgba(128, 128, 128, 1)">&gt;</span>", <span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)"> &lt;roles&gt; </span><span style="color: rgba(255, 0, 0, 1)">]</span>, { <span style="color: rgba(128, 128, 128, 1)">&lt;</span>writeConcern<span style="color: rgba(128, 128, 128, 1)">&gt;</span> } )</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; show users;
{
    "_id" : "products.user123",
    "userId" : UUID("b71e3c9d-1e57-<span style="font-weight: bold">4178</span>-b6f8-48445ee2ebfc"),
    "user" : "user123",
    "db" : "products",
    "roles" : [
      {
            "role" : "read",
            "db" : "products"
      }
    ],
    "customData" : {
      "name" : "运维账号"
    },
    "mechanisms" : [
      "SCRAM-SHA-1",
      "SCRAM-SHA-256"
    ]
}<br>
&gt; <strong><span style="color: rgba(255, 0, 0, 1)">db.grantRolesToUser('user123',['readWrite',{role:'read',db:'test'}])</span> </strong>
<br>&gt; show users;
{
    "_id" : "products.user123",
    "userId" : UUID("b71e3c9d-1e57-<span style="font-weight: bold">4178</span>-b6f8-48445ee2ebfc"),
    "user" : "user123",
    "db" : "products",
    "roles" : [
      {
            "role" : "readWrite",
            "db" : "products"
      },
      {
            "role" : "read",
            "db" : "test"
      },
      {
            "role" : "read",
            "db" : "products"
      }
    ],
    "customData" : {
      "name" : "运维账号"
    },
    "mechanisms" : [
      "SCRAM-SHA-1",
      "SCRAM-SHA-256"
    ]
}</span></pre>
</div>
<p><span style="font-size: 16px"><strong>说明:</strong>在已有用户(user123)的权限下,新增当前库(products)的readWrite role和test库的read role。</span></p>
<p><span style="font-size: 16px">9,移除指定用户的role:<code class="descclassname">db.</code><code class="descname">revokeRolesFromUser</code><span class="sig-paren">(<span class="sig-paren">)</span></span></span></p>
<p><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre>db.revokeRolesFromUser( "<span style="color: rgba(128, 128, 128, 1)">&lt;</span>username<span style="color: rgba(128, 128, 128, 1)">&gt;</span>", <span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)"> &lt;roles&gt; </span><span style="color: rgba(255, 0, 0, 1)">]</span>, { <span style="color: rgba(128, 128, 128, 1)">&lt;</span>writeConcern<span style="color: rgba(128, 128, 128, 1)">&gt;</span> } )</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; show users;
{
    "_id" : "products.user123",
    "userId" : UUID("b71e3c9d-1e57-<span style="font-weight: bold">4178</span>-b6f8-48445ee2ebfc"),
    "user" : "user123",
    "db" : "products",
    "roles" : [
      {
            "role" : "readWrite",
            "db" : "products"
      },
      {
            "role" : "read",
            "db" : "test"
      },
      {
            "role" : "read",
            "db" : "products"
      }
    ],
    "customData" : {
      "name" : "运维账号"
    },
    "mechanisms" : [
      "SCRAM-SHA-1",
      "SCRAM-SHA-256"
    ]
}

&gt; db.revokeRolesFrom
db.revokeRolesFromRole(db.revokeRolesFromUser(

&gt;<span style="color: rgba(255, 0, 0, 1)"><strong> db.revokeRolesFromUser('user123',[{role:'read',db:'test'},'readWrite'])</strong></span>
<br>&gt; show users;
{
    "_id" : "products.user123",
    "userId" : UUID("b71e3c9d-1e57-<span style="font-weight: bold">4178</span>-b6f8-48445ee2ebfc"),
    "user" : "user123",
    "db" : "products",
    "roles" : [
      {
            "role" : "read",
            "db" : "products"
      }
    ],
    "customData" : {
      "name" : "运维账号"
    },
    "mechanisms" : [
      "SCRAM-SHA-1",
      "SCRAM-SHA-256"
    ]
}</span></pre>
</div>
<p><span style="font-size: 16px"><strong>说明:</strong>移除已有用户(user123)在当前库(products)的readWrite role和test库的read role权限。</span></p>
<p><span style="font-size: 16px">10,用户认证:db.auth(username,password)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span> db.auth(<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">dba</span><span style="color: rgba(255, 0, 0, 1)">'</span>,<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">DBA</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">1</span></pre>
</div>
<p><span style="font-size: 16px">以上说明的role都是内置角色,用户自定义角色可以看官方文档说明。</span></p>
<h2>角色管理</h2>
<p><span style="font-size: 16px">1,创建角色:db.createRole(role, writeConcern)</span></p>
<p><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
role: "</span><span style="color: rgba(128, 128, 128, 1)">&lt;</span>name<span style="color: rgba(128, 128, 128, 1)">&gt;</span>",      <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">新角色的名称</span>
<span style="color: rgba(0, 0, 0, 1)"> privileges: [
   { <strong>resource</strong>: { &lt;resource&gt; }, <strong>actions</strong>: [ "&lt;action&gt;", ... ]</span><span style="color: rgba(0, 0, 0, 1)"> },
   ...
],      </span><span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">权限,由resource和actions组成。空数组表示无权限</span>
roles:<span style="color: rgba(0, 0, 0, 1)"> [
   { role: "&lt;role&gt;", db: "&lt;database&gt;" } | "&lt;role&gt;",
      ...
],</span>   <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">角色的数组,此角色从中继承特权,空数组表示没有继承角色</span>
authenticationRestrictions: <span style="color: rgba(0, 0, 0, 1)">[
    {
      clientSource: ["&lt;IP&gt;" | "&lt;CIDR range&gt;", ...],
      serverAddress: ["&lt;IP&gt;" | "&lt;CIDR range&gt;", ...]</span><span style="color: rgba(0, 0, 0, 1)">
    },
    ...
]    </span><span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">验证限制</span>
}</pre>
</div>
<p><span style="font-size: 16px"><strong>resource</strong>表示资源,</span><span style="font-size: 16px">包括database或collection也可以是database和collection的组合:</span></p>
<p><span style="font-size: 16px">{ db: &lt;database&gt;, collection: &lt;collection&gt; }</span></p>
<p><span style="font-size: 16px"><strong>actions</strong>表示权限操作,"actions" 定义了"user"能够对 "resource document"执行的操作:</span></p>
<p><span style="font-size: 16px">find、insert、remove、update</span></p>
<p><span style="font-size: 16px"><strong>privilege</strong>表示权限,"privilege" 是一组"resource" 和 "actions" 的组,关于privileges的详细信息见官方说明,里面有各个命令的权限说明<br></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt;db.createRole(
   {role:"zhoujy", //角色名称
       privileges: [ // 权限集
      {resource: //资源
         {db:"xxx",   // 创建的zhoujy角色具有对xxx库的操作权限,具体权限见actions
          collection:""   // xxx库下对应的集合名 如果为"" 表示所有集合
         },
          actions: [ "find", "insert", "remove","update" ]   //角色可进行的操作,注意这里是一个数组
      }
                   ],
         roles: [{ role: "read", db: "admin" }] // 是否继承其他的角色,如果指定了其他角色那么新创建的角色自动继承对应其他角色的所有权限,该参数必须显示指定
   },
{ w: "majority" , wtimeout: <span style="font-weight: bold">5000</span> }
)</span></pre>
</div>
<p><span style="font-size: 16px">说明:创建了一个zhoujy的role,可以像内置角色一样来使用。</span></p>
<p><span style="font-size: 16px">2,查看指定角色信息:db.getRole(rolename, args)</span></p>
<p><span style="font-size: 16px">参数:</span></p>
<p><span style="font-size: 16px">showBuiltinRoles:可选,在输出中返回内置角色信息</span></p>
<p><span style="font-size: 16px">showPrivileges:可选,在输出中返回权限信息</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; <strong>db.getRole('zhoujy')</strong>
{
    "role" : "zhoujy",
    "db" : "admin",
    "isBuiltin" : false,
    "roles" : [ ],
    "inheritedRoles" : [ ]
}

&gt; <strong>db.getRole('zhoujy',{showPrivileges: true})</strong>
{
    "role" : "zhoujy",
    "db" : "admin",
    "isBuiltin" : false,
    "roles" : [ ],
    "inheritedRoles" : [ ],
    "privileges" : [
      {
            "resource" : {
                "db" : "xxx",
                "collection" : ""
            },
            "actions" : [
                "find",
                "insert",
                "remove",
                "update"
            ]
      }
    ],
    "inheritedPrivileges" : [
      {
            "resource" : {
                "db" : "xxx",
                "collection" : ""
            },
            "actions" : [
                "find",
                "insert",
                "remove",
                "update"
            ]
      }
    ]
}</span></pre>
</div>
<p><span style="font-size: 16px">3,查看当前数据库中所有的角色信息:db.getRoles()</span></p>
<p><span style="font-size: 16px">不带参数运行,返回数据库用户定义角色的继承信息,参数:</span></p>
<p><span style="font-size: 16px">rolesInfo:1,返回所有用户定义的角色信息</span></p>
<p><span style="font-size: 16px">showPrivileges:true,返回所有用户的权限信息</span></p>
<p><span style="font-size: 16px">showBuiltinRoles:true,返回内置角色信息</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt;<strong>db.getRoles</strong>(
    {
      rolesInfo: </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">1</span><span style="color: rgba(0, 0, 0, 1)">,
      showPrivileges:true,
      showBuiltinRoles: true
    }
)</span></pre>
</div>
<p><span style="font-size: 16px">4,角色授权:db.grantPrivilegesToRole(rolename, privileges, writeConcern)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; <strong>db.grantPrivilegesToRole</strong>(
"zhoujy",
[
    {
      resource: { db: "products", collection: "" },
      actions: [ "insert","find"]</span><span style="color: rgba(0, 0, 0, 1)">
    }
],
{ w: "majority" }
)</span></pre>
</div>
<p><span style="font-size: 16px">说明:在已有的role下面,再追加权限。</span></p>
<p><span style="font-size: 16px">5,角色权限回收:db.revokePrivilegesFromRole(rolename, privileges, writeConcern)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; db.revokePrivilegesFromRole(
"zhoujy",
[
    {
      resource: { db: "products", collection: "" },
      actions: [ "insert" ]
    }
],
{ w: "majority" }
)</span></pre>
</div>
<p><span style="font-size: 16px">说明:在已有的role下面,删除权限。</span></p>
<p><span style="font-size: 16px">6,角色继承:<code class="descclassname">db.</code><code class="descname">grantRolesToRole</code><span class="sig-paren">(rolename,&nbsp;roles,&nbsp;writeConcern<span class="sig-paren">)</span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)"><strong> db.grantRolesToRole</strong>(
          "zhoujy",
         [ "zhoujy1","zhoujy2" ],
         { w: "majority" , wtimeout: <span style="font-weight: bold">5000</span> }
                  )</span></pre>
</div>
<p><span style="font-size: 16px">说明:将 zhoujy1、zhoujy2 两个角色(假设之前已经创建好)的权限授予zhoujy角色</span></p>
<p><span style="font-size: 16px">7,继承角色回收:&nbsp;<code class="descclassname">db.</code><code class="descname">revokeRolesFromRole</code><span class="sig-paren">(rolename,&nbsp;roles,&nbsp;writeConcern<span class="sig-paren">)</span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">db.revokeRolesFromRole(
          "zhoujy" ,
          </span><span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)"> "zhoujy2" </span><span style="color: rgba(255, 0, 0, 1)">]</span><span style="color: rgba(0, 0, 0, 1)">
                      ) </span></pre>
</div>
<p><span style="font-size: 16px">说明:撤销zhoujy角色从zhoujy2角色所继承的所有权限</span></p>
<p><span style="font-size: 16px">8,更新角色:<code class="descclassname">db.</code><code class="descname">updateRole</code><span class="sig-paren">(rolename,&nbsp;update,&nbsp;writeConcern<span class="sig-paren">)</span></span></span></p>
<p><span style="font-size: 16px">格式:</span></p>
<div class="cnblogs_code">
<pre>    "<span style="color: rgba(128, 128, 128, 1)">&lt;</span>rolename<span style="color: rgba(128, 128, 128, 1)">&gt;</span>",<span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">角色名</span>
<span style="color: rgba(0, 0, 0, 1)">    {
   </span> <span style="color: rgba(0, 0, 0, 1)">privileges:
          [
            { resource: { &lt;resource&gt; }, actions: [ "&lt;action&gt;", ... ] },
            ...</span><span style="color: rgba(0, 0, 0, 1)">
          ],</span><span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">权限</span>
<span style="color: rgba(0, 0, 0, 1)">      roles:
          </span><span style="color: rgba(0, 0, 0, 1)">[
            { role: "&lt;role&gt;", db: "&lt;database&gt;" } | "&lt;role&gt;",
            ...
          ],</span>   <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">角色</span>
<span style="color: rgba(0, 0, 0, 1)">      authenticationRestrictions:
          </span><span style="color: rgba(0, 0, 0, 1)">[
            {
            clientSource: ["&lt;IP&gt;" | "&lt;CIDR range&gt;", ...],
            serverAddress: ["&lt;IP&gt;", | "&lt;CIDR range&gt;", ...]</span><span style="color: rgba(0, 0, 0, 1)">
            },
            ...
          ]
    },    </span><span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)"> 限制</span>
    { <span style="color: rgba(128, 128, 128, 1)">&lt;</span>writeConcern<span style="color: rgba(128, 128, 128, 1)">&gt;</span> } <span style="color: rgba(0, 128, 128, 1)">--</span><span style="color: rgba(0, 128, 128, 1)">写关注</span>
)</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">&gt; <strong>db.updateRole</strong>(
   "zhoujy",
   {
      </span><span style="color: rgba(0, 0, 255, 1)">privileges</span><span style="color: rgba(0, 0, 0, 1)">:
      </span><span style="color: rgba(255, 0, 0, 1)">[</span><span style="color: rgba(255, 0, 0, 1)">
      {
      resource:{db:"xxx", collection:""},
      actions: [ "find", "insert", "remove","update" </span><span style="color: rgba(255, 0, 0, 1)">]</span><span style="color: rgba(0, 0, 0, 1)">
      }
       ],
      roles: </span><span style="color: rgba(255, 0, 0, 1)">[]</span><span style="color: rgba(0, 0, 0, 1)">
   },
{ w: "majority" , wtimeout: </span><span style="color: rgba(128, 0, 0, 1); font-weight: bold">5000</span><span style="color: rgba(0, 0, 0, 1)"> }
)</span></pre>
</div>
<p><span style="font-size: 16px">9,删除角色:<code class="descclassname">db.</code><code class="descname">dropRole</code><span class="sig-paren">(rolename,&nbsp;writeConcern<span class="sig-paren">)</span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 128, 128, 1)">&gt;</span> db.dropRole(<span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">myClusterwideAdmin</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, { w: "majority" })
true</span></pre>
</div>
<p><span style="font-size: 16px">10,删除当前库所有用户自定义的角色:<code class="descclassname">db.</code><code class="descname">dropAllRoles</code><span class="sig-paren">(writeConcern<span class="sig-paren">)</span></span></span></p>
<div class="cnblogs_code">
<pre>db.dropAllRoles( { w: "majority" } )</pre>
</div>
<p><span style="font-size: 16px">到此,关于用户管理的已经介绍完,更多的详细信息可以见官网说明,或可以查阅</span><span style="font-size: 16px">MongoDB 权限控制系统简介。</span><span style="font-size: 16px">需要注意的是,需要开启服务器参数中的<strong>security.authorization:true</strong>,才会使用用户验证(db.auth())。</span></p>
<h2>总结</h2>
<p><span style="font-size: 16px">本文大致介绍了MongoDB用户管理的使用说明,后续根据需要会持续更新本文。关于用户管理的更多说明可以看</span><span style="font-size: 16px">官方文档<br></span></p>
<h2>&nbsp;</h2>
<h2>参考文章:</h2>
<p class="postTitle"><span style="font-size: 16px">MongoDB 3.0 用户创建</span></p>
<p class="postTitle"><span style="font-size: 16px">MongoDB 权限控制系统简介</span></p>
<p class="postTitle">&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    ~~~~~~~~~~~~~~~
万物之中,希望至美
~~~~~~~~~~~~~~~<br><br>
来源:https://www.cnblogs.com/zhoujinyi/p/13440477.html
頁: [1]
查看完整版本: MongoDB 4.2 用户管理