Mongodb 认证鉴权那点事
一、Mongodb 的权限管理
认识权限管理,说明主要概念及关系
与大多数数据库一样,Mongodb同样提供了一套权限管理机制。
为了体验Mongodb 的权限管理,我们找一台已经安装好的Mongodb,可以参照这里搭建一个单节点的Mongodb。
直接打开mongo shell:
./bin/mongo --port=27017
尝试执行stats命令以查看appdb数据库的状态:
MongoDB Enterprise > use appdb
MongoDB Enterprise > db.stats()
{
"ok" : 0,
"errmsg" : "not authorized on nscl to execute command { dbstats: 1.0, scale: undefined }",
"code" : 13
}
此时的提示正是说明你当前的操作没有获得许可,使用appdb预创建的用户进行鉴权:
> db.auth('appuser','yourpassword')
1
> db.stats()
{
"db" : "appdb",
"collections" : 0,
"views" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"ok" : 1
}
可以发现,在通过验明身份之后,stats操作的鉴权获得了许可。
以上例子可能让你对数据库鉴权有了点浅显认识,那么接下来开始说点概念了,大致是叫基于角色的权限控制

[图-角色权限控制]
先解释下图中的几个实体:
- Resource,资源
一个资源可以是一个数据库、集合、或者一个集群..往大了说,任何可能被操作的事物都可以被当做资源。 - Action,动作
动作是指对资源的一个执行行为,比如读取表、读取数据库,其中读取便是一个动作。 - Privilege,权限
权限指的是对某类或某一些资源执行某些动作的允许,与Permission的意义一致。 - Role,角色
系统中的角色,通常是代表了一种权力等级的象征,比如论坛中的管理员、版主、游客等等,就是角色;
系统定义中,角色往往代表一组权限的集合。 - User,用户
可登录系统的实体,一个用户通常可被赋予多个角色。
噢,关于图的简单解释:
权限定义了对某些资源的某些操作,角色则可以拥有多个权限;
用户User可以被赋予多个角色,从而获得这些角色所拥有的权限以操作某些资源。
对于Mongodb来说,只要开启鉴权,所有的DB访问操作都需要通过权限检查。而大致的操作流程跟下图类似

[图-mongo鉴权]
- Mongodb 的用户归属于某个数据库,用户需要在所属的数据库中进行鉴权;
- 一旦通过鉴权,当前的会话(连接)中所有操作将按照用户被赋予的角色权限执行检查。
二、鉴权方式
阐述Mongodb支持的几种鉴权方式
鉴权方式是指Mongodb如何识别接入用户,如何检查权限是否合法的一系列校验机制。
SCRAM-SHA-1
SCRAM-SHA-1 是默认的鉴权机制,定义于 IETF standard, RFC 5802
是一种安全性较高的"挑战-应答"鉴权机制。关于"挑战-应答"可以参考维基百科MongoDB Challenge and Response (MONGODB-CR)
3.0 以前采用的机制,已经废弃x.509 Certificate Authentication.
基于证书的鉴权,采用该方式可建立 SSL/TLS 加密连接LDAP proxy authentication
基于LDAP 系统的鉴权,仅企业版支持Kerberos authentication
基于Kerberos 的鉴权,仅企业版支持
SCRAM-SHA-1 是当前推荐使用的鉴权方式,既然如此,有必要上图继续解释:

步骤解读
- 客户端发起一个SCRAM鉴权请求;
鉴权参数中带上用户名、客户端随机字符串(防止重放攻击); - 服务端发出一个挑战响应;
服务侧先检查用户名,通过后生成一个salt因子、迭代数、合并字符串(包含客户端随机串和服务端随机串) - 客户端响应一个proof(证明数据)和合并字符串;
响应的 proof数据根据服务所给的随机参数以及客户端密钥生成,是一个客户端签名与密钥异或计算后的结果; - 服务端将存储的密钥结合随机参数,使用同样的算法生成签名并校验客户端 proof数据;
若校验通过,服务端采用类似方式发送自己的签名; - 客户端校验服务端签名数据。
可以看到,SCRAM鉴权时也类似SSL/TLS 的握手过程,但相比之下简单许多,同时在性能方面也要具备优势;
然后我们看看安全性的部分:
- 信息窃听,传输过程中全部采用动态签名,保证密码不会被传输;
- 重放攻击,由于使用了随机数,每次生成的数据都不一样,可避免重复数据攻击;
- 服务假冒,鉴权过程是双向的,即客户端会校验服务端身份,而服务端密钥也根据密码生成,中间人无法仿造;
- 存储安全,密码在数据库中均没有明文存储,都通过不可逆的算法加密存储。
另外SCRAM-SHA-1 相比MONGODB-CR的优势还有:
A tunable work factor (iterationCount),
可灵活调整的安全系数
Per-user random salts rather than server-wide salts
每个用户有独立的随机系数
A cryptographically stronger hash function (SHA-1 rather than MD5),
更安全的hash函数
Authentication of the server to the client as well as the client to the server.
支持双向认证
对 SCRAM-SHA-1的实现感兴趣?戳这里
三、内部鉴权
副本集、分片集群内鉴权方式
内部鉴权是指 Mongo集群内部节点之间进行访问的鉴权方式,比如副本集内主备之间的访问、分片集群内Mongos 与Mongod之间的访问。
内部鉴权目前支持两种方式:
KeyFiles
密钥文件方式,采用SCRAM-SHA-1 的鉴权机制,文件内包含了一个共享密钥,由集群内所有成员共同持有。
通常,密钥的长度在6-1024字符内,采用Base64编码。
如何使用?X.509 证书
证书鉴权,用于SSL/TLS加密连接通道。
如何使用?
四、数据库角色
针对Mongodb数据库中的各种角色进行说明
数据库访问
| 角色名称 | 拥有权限 |
|---|---|
| read | 允许读取指定数据库的角色 |
| readWrite | 允许读写指定数据库的角色 |
数据库管理
| 角色名称 | 拥有权限 |
|---|---|
| dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
| userAdmin | 允许管理当前数据库的用户,如创建用户、为用户授权 |
| dbOwner | 数据库拥有者(最高),集合了dbAdmin/userAdmin/readWrite角色权限 |
集群管理
| 角色名称 | 拥有权限 |
|---|---|
| clusterAdmin | 集群最高管理员,集合clusterManager/clusterMonitor/hostManager角色权限 |
| clusterManager | 集群管理角色,允许对分片和副本集集群执行管理操作,如addShard,resync等 |
| clusterMonitor | 集群监控角色,允许对分片和副本集集群进行监控,如查看serverStatus |
| hostManager | 节点管理角色,允许监控和管理节点,比如killOp、shutdown操作 |
备份恢复
| 角色名称 | 拥有权限 |
|---|---|
| backup | 备份权限,允许执行mongodump操作 |
| restore | 恢复权限,允许执行mongoresotre操作 |
数据库通用角色
| 角色名称 | 拥有权限 |
|---|---|
| readAnyDatabase | 允许读取所有数据库 |
| readWriteAnyDatabase | 允许读写所有数据库 |
| userAdminAnyDatabase | 允许管理所有数据库的用户 |
| dbAdminAnyDatabase | 允许管理所有数据库 |
特殊角色
| 角色名称 | 拥有权限 |
|---|---|
| root | 超级管理员,拥有所有权限 |
| __system | 内部角色,用于集群间节点通讯 |
基本是这些,有兴趣可看看官方的内置角色
Mongodb 的用户及角色数据一般位于当前实例的 admin数据库,system.users存放了所有数据;
存在例外的情况是分片集群,应用接入mongos节点,鉴权数据则存放于config节点。因此有时候为了方便分片集群管理,会单独为分片内部节点创建独立的管理操作用户;
五、相关操作
简单列举用户权限相关的常用操作
授权启动
./bin/mongod --auth
默认为非授权启动
也可以通过security.authorization配置指定
创建管理员用户
use admin
db.createUser({
user:'admin',pwd:'admin@2016',roles:[
{role:'clusterAdmin',db:'admin'},
{role:'userAdminAnyDatabase',db:'admin'}
]})
创建用户
use appdb
db.createUser({user:'appuser',pwd:'appuser@2016'})
授予权限
use appdb
db.grantRolesToUser("appuser", [{role:'readWrite',db:'appdb'}])
删除权限
use appdb
db.revokeRolesFromUser("appuser",[{ role: "read", db: "appdb" }])
六、常见问题
shell 操作提示错误
use appdb
MongoDB Enterprise > db.stats()
{
"ok" : 0,
"errmsg" : "not authorized on appdb to execute command { dbstats: 1.0, scale: undefined }",
"code" : 13
}
原因:当前连接未鉴权或用户没有操作权限
解决:为用户分配适当权限,并执行auth操作,如下:
db.auth('appuser','yourpassword');
无法执行 eval 操作
db.eval() 是一个全局操作,可执行任意数据库脚本;
执行该命令需要拥有anyAction或anyResource的权限,通常不建议为数据库用户赋予这样的权限。
该命令存在安全风险,已不建议使用(mongodb 3.0之后已经过期)。
七、扩展阅读
Mongodb 鉴权机制
https://docs.mongodb.com/manual/core/authentication/
Mongodb 内置角色介绍
https://docs.mongodb.com/manual/reference/built-in-roles/#database-user-roles
Mongodb 权限操作介绍
https://docs.mongodb.com/manual/reference/privilege-actions/#security-user-actions
运维-Mongodb鉴权介绍
http://www.ywnds.com/?p=5635
Mongodb 认证鉴权那点事的更多相关文章
- 基于Springboot集成security、oauth2实现认证鉴权、资源管理
1.Oauth2简介 OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAu ...
- 认证鉴权与API权限控制在微服务架构中的设计与实现(四)
引言: 本文系<认证鉴权与API权限控制在微服务架构中的设计与实现>系列的完结篇,前面三篇已经将认证鉴权与API权限控制的流程和主要细节讲解完.本文比较长,对这个系列进行收尾,主要内容包括 ...
- Spring Security 接口认证鉴权入门实践指南
目录 前言 SpringBoot 示例 SpringBoot pom.xml SpringBoot application.yml SpringBoot IndexController SpringB ...
- nginx 请求文件 进行用户认证/鉴权: internal(限制为内部调用)
在进行WEB开发时, 必然会遇到向用户返回文件的场景(如图片, 文档等等), 当返回的文件较小时, 我们可以直接通过接口以数据流的形式向前台返回, 因为文件较小, 因此也不会太过于影响响应速度及服务器 ...
- web系统认证与鉴权中的一些问题
认证鉴权系统的初心: 空间管理: 1.他是谁? 他登陆了没有? 2.他要做什么? 2.1 他要使用什么功能? 他是否有这个功能的权限. 2.2 他要使用这个功能做什么操作? 他是否有这个功能的这个操作 ...
- 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...
- 关于防范csrf攻击基于token鉴权
在web开发中,之前都使用cookie + session方式来实现身份认证鉴权.但是现在前后端分离,以及终端有可能不支持cookie的情况下,一般都采用token方式.现在系统设计思路如下: 服务端 ...
- mongodb 3.4 分片 一主 一副 一仲 鉴权集群部署.
Docker方式部署 为了避免过分冗余,并且在主节点挂了,还能顺利自动提升,所以加入仲裁节点 mongodb版本: 环境:一台虚拟机 三个configsvr 副本: 端口为 27020,27021,2 ...
- 搭建一个分布式MongoDB鉴权集群
今天休假在家,测试并搭建了一个replica set shard MongoDB鉴权集群.replica set shard 鉴权集群中文资料比较少,本文是个人笔记,同时也希望对后来者有所帮助.本文仅 ...
随机推荐
- 201521123011《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 参考资料: 百度脑图 XMind 2. 书面作业 作业参考文件下载 1.代码阅读:Child压缩包内源代码 1.1 com.p ...
- 201521123080《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 1.网络编程概述 (1)网络模型 OSI参考模型 TCP/IP参考模型 (2)网络通讯要素 IP地址 端口 ...
- Java:java中BufferedReader的read()及readLine()方法的使用心得
BufferedReader的readLine()方法是阻塞式的, 如果到达流末尾, 就返回null, 但如果client的socket末经关闭就销毁, 则会产生IO异常. 正常的方法就是使用sock ...
- python 浅析对return的理解
最近很忙,但是还是很认真的学习python这个东西,不是出于什么目的,只是单纯的喜欢罢了.最近学习的东西比较简单,但是也遇到了一些问题,就是比较迷惑人的问题,今天小编就在这里讲讲自己的对return的 ...
- oracle 建表空间->创建用户并把表空间分配给用户->给用户授权->导库
首先注意:我参考网上使用的sysdba模式(normal)登陆的,其他的模式建不了用户(个人没有进行其他模式的表空间尝试,如有人尝试欢迎补充,感激不尽) 表空间相当于表的容器(一下所有的操作都适用于o ...
- Spring第六篇【Spring AOP模块】
前言 Spring的第五篇也算是AOP编程的开山篇了,主要讲解了代理模式-..本博文主要讲解Spring的AOP模块:注解方式和XML方式实现AOP编程.切入点表达式.. AOP的概述 Aop: as ...
- SpringSecurity 登录 - 以及Md5加密
我们现在开放一个链接给其他系统,来访问我们的系统 http://localhost:8080/hulk-teller-web/haihui!init.jspa?loginId=teller01& ...
- 翻译一篇关于jedis的文章
翻译 自 http://www.baeldung.com/jedis-java-redis-client-libraryIntro to Jedis – the Java Redis Client L ...
- [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)
接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...
- 学习ExtJS的grid布局
这是之前学习ExtJS布局的时候我导师让我重点熟悉的内容.之后会发一个最近写的结合MVC项目的grid布局的案例. 上一篇关于ExtJS的学习资料什么的都已经更在上一篇了,这里只是对一些代码的记录. ...