3.6. 身份验证和授权¶
3.6.1. 服务器管理员¶
- [admins]¶
在版本 3.0.0 中更改: CouchDB 需要一个管理员帐户才能启动。如果没有创建管理员帐户,CouchDB 将打印错误消息并终止。
CouchDB 服务器管理员和密码不存储在 _users
数据库中,而是存储在 CouchDB 加载其 ini 文件时找到的最后一个 [admins]
部分中。有关配置文件顺序和行为的详细信息,请参阅 :config:intro。此文件(可能是 /opt/couchdb/etc/local.ini
或 /opt/couchdb/etc/local.d/10-admins.ini
,当 CouchDB 从软件包安装时)应适当保护,并且只能由系统管理员读取。
[admins]
;admin = mysecretpassword
admin = -hashed-6d3c30241ba0aaa4e16c6ea99224f915687ed8cd,7f4a3e05e0cbc6f48a0035e3508eef90
architect = -pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000
管理员可以直接添加到 [admins]
部分,当 CouchDB 重新启动时,密码将被加盐和加密。您也可以使用 HTTP 接口创建管理员帐户;这样,您无需重新启动 CouchDB,也不需要临时存储或以明文形式传输密码。HTTP /_node/{node-name}/_config/admins
端点支持查询、删除或创建新的管理员帐户。
GET /_node/nonode@nohost/_config/admins HTTP/1.1
Accept: application/json
Host: localhost:5984
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 196
Content-Type: application/json
Date: Fri, 30 Nov 2012 11:37:18 GMT
Server: CouchDB (Erlang/OTP)
{
"admin": "-hashed-6d3c30241ba0aaa4e16c6ea99224f915687ed8cd,7f4a3e05e0cbc6f48a0035e3508eef90",
"architect": "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
}
如果您已经拥有加盐的加密密码字符串(例如,来自旧的 ini 文件或来自不同的 CouchDB 服务器),那么您可以存储“原始”加密字符串,而无需让 CouchDB 对其进行双重加密。
PUT /_node/nonode@nohost/_config/admins/architect?raw=true HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 89
Host: localhost:5984
"-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 89
Content-Type: application/json
Date: Fri, 30 Nov 2012 11:39:18 GMT
Server: CouchDB (Erlang/OTP)
"-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
有关详细信息,请参阅 security,包括配置 PBKDF2
的工作因子,以及 PBKDF2 (RFC-2898) 中的算法本身。
在版本 1.4 中更改: 添加了 PBKDF2 服务器端哈希加盐密码支持,现在作为 _config/admins
API 的同步调用。
3.6.2. 身份验证配置¶
- [chttpd]¶
- require_valid_user¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd] 部分
当此选项设置为
true
时,不允许匿名用户发出任何请求。每个人都必须经过身份验证。[chttpd] require_valid_user = false
- require_valid_user_except_for_up¶
当此选项设置为
true
时,不允许匿名用户发出任何请求,除了/_up
端点。其他所有人必须经过身份验证。[chttpd] require_valid_user_except_for_up = false
- [chttpd_auth]¶
在版本 3.2 中更改: 这些选项已移至 [chttpd_auth] 部分:authentication_redirect、timeout、auth_cache_size、allow_persistent_cookies、iterations、min_iterations、max_iterations、secret、users_db_public、x_auth_roles、x_auth_token、x_auth_username、cookie_domain、same_site。
- allow_persistent_cookies¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
当设置为
true
时,CouchDB 将在 cookie 上设置 Max-Age 和 Expires 属性,这会导致用户代理(如浏览器)在重启时保留 cookie。[chttpd_auth] allow_persistent_cookies = true
- cookie_domain¶
在版本 2.1.1 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
配置
AuthSession
cookie 的domain
属性。默认情况下,domain
属性为空,导致 cookie 设置在 CouchDB 的域上。[chttpd_auth] cookie_domain = example.com
- same_site¶
在版本 3.0.0 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
当此选项设置为非空值时,将向
AuthSession
cookie 添加SameSite
属性。有效值为none
、lax
或strict
。[chttpd_auth] same_site = strict
- auth_cache_size¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
在内存中缓存的 用户上下文对象 数量,以减少磁盘查找。
[chttpd_auth] auth_cache_size = 50
- authentication_redirect¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
指定在成功身份验证后重定向的位置,前提是客户端接受
text/html
响应(通过Accept
标头)。[chttpd_auth] authentication_redirect = /_utils/session.html
- hash_algorithms¶
在版本 3.3 中新增。
注意
在 CouchDB 3.3.1 版本之前,代理身份验证 仅使用哈希算法
sha1
来验证X-Auth-CouchDB-Token
。设置用于 cookie 和代理身份验证的 HMAC 哈希算法。您可以提供一个用逗号分隔的哈希算法列表。新的 cookie 会话或会话更新将使用第一个哈希算法进行计算。列表中的所有值都可以用于解码 cookie 会话和用于 代理身份验证 的令牌
X-Auth-CouchDB-Token
。[chttpd_auth] hash_algorithms = sha256, sha
注意
您可以选择 CouchDB 安装中使用的 Erlang 版本支持的任何哈希算法。常见的可用哈希列表可能是
sha, sha224, sha256, sha384, sha512
要检索支持的哈希算法的完整列表,您可以使用我们的
bin/remsh
脚本,并使用crypto:supports(hashs).
检索可用哈希算法的完整列表,或者使用 _node/$node/_versions 端点检索哈希。警告
我们不建议使用以下哈希算法
md4, md5
- iterations¶
在版本 1.3 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
PBKDF2 算法对密码进行哈希处理的迭代次数。次数越多,哈希的持久性越好,但每次需要身份验证的请求的性能成本也会增加。当使用数十万次迭代时,请使用会话 cookie,否则性能损失将非常大。(内部哈希算法是 SHA1,这会影响推荐的迭代次数。)
[chttpd_auth] iterations = 10000
- min_iterations¶
在版本 1.6 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
PBKDF2 算法对密码进行哈希处理时允许的最小迭代次数。任何迭代次数少于此的用户都将被禁止。
[chttpd_auth] min_iterations = 100
- max_iterations¶
在版本 1.6 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
PBKDF2 算法对密码进行哈希处理时允许的最大迭代次数。任何迭代次数大于此的用户都将被禁止。
[chttpd_auth] max_iterations = 100000
- password_regexp¶
在版本 3.2 中新增。
用于检查新密码/更改密码的 正则表达式 列表。设置后,新用户密码必须与列表中的所有正则表达式匹配。
正则表达式可以与原因文本配对:
[{"RegExp", "reason text"}, ...]
。如果正则表达式不匹配,其原因文本将附加到默认原因Password does not conform to requirements.
。[couch_httpd_auth] ; Password must be 10 chars long and have one or more uppercase and ; lowercase char and one or more numbers. password_regexp = [{".{10,}", "Min length is 10 chars."}, "[A-Z]+", "[a-z]+", "\\d+"]
- proxy_use_secret¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
当此选项设置为
true
时,chttpd_auth/secret
选项对于 代理身份验证 是必需的。[chttpd_auth] proxy_use_secret = false
- public_fields¶
版本 1.4 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
用户文档(在
couchdb/users_db_suffix
中)中可以被任何用户读取的字段名称的逗号分隔列表。如果未设置或未指定,则经过身份验证的用户只能检索自己的文档。[chttpd_auth] public_fields = first_name, last_name, contacts, url
注意
使用
public_fields
允许列表的用户文档属性需要将chttpd_auth/users_db_public
选项设置为true
(后者选项没有其他用途)。[chttpd_auth] users_db_public = true
- secret¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
秘密令牌用于 代理身份验证 和 Cookie 身份验证。
[chttpd_auth] secret = 92de07df7e7a3fe14808cef90a7cc0d91
- timeout¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
自上次请求以来的秒数,在此之后会话将过期。
[chttpd_auth] timeout = 600
- users_db_public¶
版本 1.4 中新增。
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
允许所有用户查看用户文档。默认情况下,只有管理员可以浏览所有用户文档,而用户只能浏览自己的文档。
[chttpd_auth] users_db_public = false
- x_auth_roles¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
包含用户角色列表的 HTTP 标头名称(默认情况下为
X-Auth-CouchDB-Roles
),以逗号分隔。用于 代理身份验证。[chttpd_auth] x_auth_roles = X-Auth-CouchDB-Roles
- x_auth_token¶
在版本 3.2 中更改: 从 [couch_httpd_auth] 部分移至 [chttpd_auth] 部分
包含用于验证授权的令牌的 HTTP 标头名称(默认情况下为
X-Auth-CouchDB-Token
)。此令牌是根据chttpd_auth/secret
和chttpd_auth/x_auth_username
创建的 HMAC-SHA1。密钥应该在客户端和 CouchDB 节点上相同。如果chttpd_auth/proxy_use_secret
选项的值不是true
,则此令牌是可选的。用于 代理身份验证。[chttpd_auth] x_auth_token = X-Auth-CouchDB-Token
- [jwt_auth]¶
- required_claims¶
此参数是必须存在于任何呈现的 JWT 令牌中的其他强制性 JWT 声明的逗号分隔列表。如果缺少任何声明,则会发送 404 Not Found。
[jwt_auth] required_claims = exp,iat
- roles_claim_name¶
警告
roles_claim_name
在 CouchDB 3.3 中已弃用,将在以后删除。请迁移到roles_claim_path
。如果存在,作为字符串的 JSON 数组,只要 JWT 令牌有效,它将用作 CouchDB 用户的角色列表。
roles_claim_name
的默认值为_couchdb.roles
。注意
roles_claim_name
的值只能是 JWT 令牌中的顶级属性。如果设置了roles_claim_path
,则忽略roles_claim_name
!假设我们有以下配置
[jwt_auth] roles_claim_name = my-couchdb.roles
CouchDB 将在 JWT 令牌中搜索属性
my-couchdb.roles
。{ "my-couchdb.roles": [ "role_1", "role_2" ] }
- roles_claim_path¶
在版本 3.3 中新增。
引入此参数是为了克服
roles_claim_name
的缺点,因为使用roles_claim_name
无法映射 JWT 令牌中的嵌套角色属性。注意
如果设置了
roles_claim_path
,则忽略roles_claim_name
!现在可以从 JWT 令牌中读取嵌套角色声明到 CouchDB 中。与往常一样,在开始运行之前有一些理论。现在不要害怕,它真的很短很简单。真的!
只有两个字符具有特殊含义。它们是
.
用于嵌套 json 属性,以及\.
用于跳过嵌套
就是这样。真的。
假设 JWT 令牌中存在以下数据有效负载
{ "resource_access": { "security.settings": { "account": { "roles": [ "manage-account", "view-profile" ] } } } }
现在,让我们为这个示例定义配置变量
roles_claim_path
。它应该看起来像这样roles_claim_path = resource_access.security\.settings.account.roles
如果属性的键中包含
.
,例如security.settings
,则必须在配置参数中使用\.
对其进行转义。如果使用.
,则它将被解释为嵌套子键。让我们用第二个示例来说明这种行为。roles_claim_name
有以下配置参数(顺便说一下,如果你没有配置它,它就是默认值)roles_claim_name = _couchdb.roles
注意
CouchDB 不会为
roles_claim_path
设置任何默认值或隐式值。要从
roles_claim_name
迁移到roles_claim_path
,你需要更改参数名称并转义.
以防止 CouchDB 将其解释为嵌套 JSON 键。roles_claim_path = _couchdb\.roles
假设你的 JWT 令牌对于你的 couchdb 角色声明具有以下数据有效负载
{ "_couchdb.roles": [ "accounting-role", "view-role" ] }
如果你一切操作正确,来自
_session
端点的响应应该看起来像这样GET /_session HTTP/1.1 Host: localhost:5984 Authorization: Bearer <JWT token>
HTTP/1.1 200 OK Content-Type: application/json
{ "ok": true, "userCtx": { "name": "1234567890", "roles": [ "accounting-role", "view-role" ] }, "info": { "authentication_handlers": [ "jwt", "proxy", "cookie", "default" ], "authenticated": "jwt" } }
就是这样,你完成了从
roles_claim_name
到roles_claim_path
的迁移。很简单,不是吗?