1.2.22. 认证¶
用于获取会话和授权数据的接口。
注解
我们也强烈推荐你 set up SSL 提高所有认证方法的安全性。
1.2.22.1. 基本身份验证¶
Basic authentication (RFC 2617 )是对CouchDB进行身份验证的一种快速而简单的方法。主要缺点是每个请求都需要发送用户凭据,这可能不安全,并且可能会影响操作性能(因为CouchDB必须在每个请求中计算密码哈希):
请求 :
GET / HTTP/1.1
Accept: application/json
Authorization: Basic cm9vdDpyZWxheA==
Host: localhost:5984
响应 :
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 177
Content-Type: application/json
Date: Mon, 03 Dec 2012 00:44:47 GMT
Server: CouchDB (Erlang/OTP)
{
"couchdb":"Welcome",
"uuid":"0a959b9b8227188afc2ac26ccdf345a6",
"version":"1.3.0",
"vendor": {
"version":"1.3.0",
"name":"The Apache Software Foundation"
}
}
1.2.22.2. Cookie身份验证¶
对于Cookie身份验证 (RFC 2109 )CouchDB生成一个令牌,客户端可以将该令牌用于接下来几个对CouchDB的请求。令牌在超时之前有效。当CouchDB在后续请求中看到有效令牌时,它将使用该令牌对用户进行身份验证,而不会再次请求密码。默认情况下,Cookie的有效期为10分钟,但 adjustable
。另外,还可以做饼干 persistent
。
要获取第一个令牌,从而第一次对用户进行身份验证, username
和 password
必须发送到 _session API 。
1.2.22.2.1. /_session
¶
-
POST
/_session
¶ 为指定的用户凭据启动新会话,方法是提供 Cookie 价值。
请求标头: - Content-Type --
- application/x-www-form-urlencoded
- application/json
查询参数: - next (string) -- 在成功登录到指定位置后强制重定向。此位置相对于服务器根目录。 可选的 .
窗体参数: - name -- 用户名
- password -- 密码
响应头: - Set-Cookie -- 授权令牌
响应JSON对象: - ok (boolean) -- 运行状态
- name (string) -- 用户名
- roles (array) -- 用户角色列表
状态代码: - 200 OK -- 已成功验证
- 302 Found -- 身份验证成功后重定向
- 401 Unauthorized -- 无法识别用户名或密码
请求 :
POST /_session HTTP/1.1 Accept: application/json Content-Length: 24 Content-Type: application/x-www-form-urlencoded Host: localhost:5984 name=root&password=relax
也可以将数据作为JSON发送:
POST /_session HTTP/1.1 Accept: application/json Content-Length: 37 Content-Type: application/json Host: localhost:5984 { "name": "root", "password": "relax" }
响应 :
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Length: 43 Content-Type: application/json Date: Mon, 03 Dec 2012 01:23:14 GMT Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/; HttpOnly {"ok":true,"name":"root","roles":["_admin"]}
如果
next
提供了查询参数如果身份验证成功,则响应将触发到指定位置的重定向:请求 :
POST /_session?next=/blog/_design/sofa/_rewrite/recent-posts HTTP/1.1 Accept: application/json Content-Type: application/x-www-form-urlencoded Host: localhost:5984 name=root&password=relax
响应 :
HTTP/1.1 302 Moved Temporarily Cache-Control: must-revalidate Content-Length: 43 Content-Type: application/json Date: Mon, 03 Dec 2012 01:32:46 GMT Location: http://localhost:5984/blog/_design/sofa/_rewrite/recent-posts Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=cm9vdDo1MEJDMDEzRTp7Vu5GKCkTxTVxwXbpXsBARQWnhQ; Version=1; Path=/; HttpOnly {"ok":true,"name":null,"roles":["_admin"]}
- Content-Type --
-
GET
/_session
¶ 返回有关已验证用户的信息,包括 用户上下文对象 ,使用的身份验证方法和数据库,以及服务器上配置的身份验证处理程序的列表。
查询参数: - basic (boolean) -- 接受 Basic Auth 通过请求此资源。 可选的 .
响应JSON对象: - ok (boolean) -- 运行状态
- userCtx (object) -- 当前用户的用户上下文
- info (object) -- 身份验证服务器配置
状态代码: - 200 OK -- 已成功验证。
- 401 Unauthorized -- 无法识别用户名或密码。
请求 :
GET /_session HTTP/1.1 Host: localhost:5984 Accept: application/json Cookie: AuthSession=cm9vdDo1MEJDMDQxRDpqb-Ta9QfP9hpdPjHLxNTKg_Hf9w
响应 :
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Length: 175 Content-Type: application/json Date: Fri, 09 Aug 2013 20:27:45 GMT Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=cm9vdDo1MjA1NTBDMTqmX2qKt1KDR--GUC80DQ6-Ew_XIw; Version=1; Path=/; HttpOnly { "info": { "authenticated": "cookie", "authentication_db": "_users", "authentication_handlers": [ "cookie", "default" ] }, "ok": true, "userCtx": { "name": "root", "roles": [ "_admin" ] } }
-
DELETE
/_session
¶ 通过指示浏览器清除cookie来关闭用户会话。从服务器的角度来看,这并不会使会话无效,因为CouchDB cookies是无状态的,因此无法做到这一点。这意味着从客户机的角度来看,调用这个端点完全是可选的,它不能防止会话cookie被窃取。
状态代码: - 200 OK -- 已成功关闭会话。
请求 :
DELETE /_session HTTP/1.1 Accept: application/json Cookie: AuthSession=cm9vdDo1MjA1NEVGMDo1QXNQkqC_0Qmgrk8Fw61_AzDeXw Host: localhost:5984
响应 :
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Length: 12 Content-Type: application/json Date: Fri, 09 Aug 2013 20:30:12 GMT Server: CouchDB (Erlang/OTP) Set-Cookie: AuthSession=; Version=1; Path=/; HttpOnly { "ok": true }
1.2.22.3. 代理身份验证¶
注解
要使用此身份验证方法,请确保 {{chttpd_auth, proxy_authentication_handler}}
值将添加到活动 chttpd/authentication_handlers
:
[chttpd]
authentication_handlers = {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, proxy_authentication_handler}, {chttpd_auth, default_authentication_handler}
Proxy authentication 如果您的应用程序已经使用了一些外部身份验证服务,并且您不希望在CouchDB中重复用户及其角色,那么它非常有用。
此身份验证方法允许创建 用户上下文对象 对于远程认证用户。默认情况下,客户端只需要通过相关请求将特定的头传递给CouchDB:
X-Auth-CouchDB-UserName
:用户名;X-Auth-CouchDB-Roles
:逗号分隔 (,
)用户角色列表;X-Auth-CouchDB-Token
:身份验证令牌。什么时候proxy_use_secret
设置(强烈建议这样做!),则此标头提供要验证的用户名的HMAC和密码令牌,以防止来自不可信来源的请求。(使用用户名的SHA1,并用密码签名)
创建令牌(使用OpenSSL的示例) :
echo -n "foo" | openssl dgst -sha1 -hmac "the_secret"
# (stdin)= 22047ebd7c4ec67dfbcbad7213a693249dbfbf86
请求 :
GET /_session HTTP/1.1
Host: localhost:5984
Accept: application/json
Content-Type: application/json; charset=utf-8
X-Auth-CouchDB-Roles: users,blogger
X-Auth-CouchDB-UserName: foo
X-Auth-CouchDB-Token: 22047ebd7c4ec67dfbcbad7213a693249dbfbf86
响应 :
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 190
Content-Type: application/json
Date: Fri, 14 Jun 2013 10:16:03 GMT
Server: CouchDB (Erlang/OTP)
{
"info": {
"authenticated": "proxy",
"authentication_db": "_users",
"authentication_handlers": [
"cookie",
"proxy",
"default"
]
},
"ok": true,
"userCtx": {
"name": "foo",
"roles": [
"users",
"blogger"
]
}
}
请注意,您不需要请求 session 如果提供了所有必需的HTTP标头,则使用此方法进行身份验证。
1.2.22.4. JWT身份验证¶
注解
要使用此身份验证方法,请确保 {{chttpd_auth, jwt_authentication_handler}}
值将添加到活动 chttpd/authentication_handlers
:
[chttpd]
authentication_handlers = {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, jwt_authentication_handler}, {chttpd_auth, default_authentication_handler}
JWT authentication
允许CouchDB使用外部生成的JWT令牌,而不是在中定义用户或角色 _users
数据库。
JWT身份验证处理程序要求所有JWT令牌都由CouchDB配置为信任的密钥签名(不支持JWT的“NONE”算法)。
另外,CouchDB可以配置为拒绝缺少一组可配置声明的JWT令牌(例如,CouchDB管理员可以坚持 exp
索赔)。
无论是否需要,JWT令牌中呈现的所有声明都将被验证。
有两个配置部分用于配置JWT身份验证;
这个 required_claims
配置设置是一个逗号分隔的列表,其中包含必须存在于任何呈现的JWT令牌中的附加强制JWT声明。A :code 400:Bad Request 如果有丢失则发送。
这个 alg
声明是必需的,因为它用于查找正确的密钥以验证签名。
这个 sub
claim是必需的,如果JWT令牌有效,它将用作CouchDB用户名。
一个叫 _couchdb.roles
是可选的。如果以JSON字符串数组的形式出现,只要JWT令牌有效,它就被用作CouchDB用户的角色列表。
; [jwt_keys]
; Configure at least one key here if using the JWT auth handler.
; If your JWT tokens do not include a "kid" attribute, use "_default"
; as the config key, otherwise use the kid as the config key.
; Examples
; hmac:_default = aGVsbG8=
; hmac:foo = aGVsbG8=
; The config values can represent symmetric and asymmetrics keys.
; For symmetrics keys, the value is base64 encoded;
; hmac:_default = aGVsbG8= # base64-encoded form of "hello"
; For asymmetric keys, the value is the PEM encoding of the public
; key with newlines replaced with the escape sequence \n.
; rsa:foo = -----BEGIN PUBLIC KEY-----\nMIIBIjAN...IDAQAB\n-----END PUBLIC KEY-----\n
; ec:bar = -----BEGIN PUBLIC KEY-----\nMHYwEAYHK...AzztRs\n-----END PUBLIC KEY-----\n
这个 jwt_key
节列出了这个CouchDB服务器信任的所有密钥。您应该确保集群的所有节点都具有相同的列表。
不包含 kid
索赔将根据 $alg:_default
关键。
出于安全原因,必须指定与每个密钥相关联的算法(特别是使用服务器信任的RSA或EC公钥呈现HMAC签名令牌:https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/).
请求 :
GET /_session HTTP/1.1
Host: localhost:5984
Accept: application/json
Content-Type: application/json; charset=utf-8
Authorization: Bearer <JWT token>
响应 :
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 188
Content-Type: application/json
Date: Sun, 19 Apr 2020 08:29:15 GMT
Server: CouchDB (Erlang/OTP)
{
"info": {
"authenticated": "jwt",
"authentication_db": "_users",
"authentication_handlers": [
"cookie",
"proxy",
"default"
]
},
"ok": true,
"userCtx": {
"name": "foo",
"roles": [
"users",
"blogger"
]
}
}
请注意,您不需要请求 session 如果提供了所需的HTTP报头,则通过此方法进行身份验证。