1.2.21. Authentication

Interfaces for obtaining session and authorization data.

1.2.21.1. Basic Authentication

Basic authentication (RFC 2617) is a quick and simple way to authenticate with CouchDB. The main drawback is the need to send user credentials with each request which may be insecure and could hurt operation performance (since CouchDB must compute the password hash with every request):

Request:

  1. GET / HTTP/1.1
  2. Accept: application/json
  3. Authorization: Basic cm9vdDpyZWxheA==
  4. Host: localhost:5984

Response:

  1. HTTP/1.1 200 OK
  2. Cache-Control: must-revalidate
  3. Content-Length: 177
  4. Content-Type: application/json
  5. Date: Mon, 03 Dec 2012 00:44:47 GMT
  6. Server: CouchDB (Erlang/OTP)
  7. {
  8. "couchdb":"Welcome",
  9. "uuid":"0a959b9b8227188afc2ac26ccdf345a6",
  10. "version":"1.3.0",
  11. "vendor": {
  12. "version":"1.3.0",
  13. "name":"The Apache Software Foundation"
  14. }
  15. }

For cookie authentication (RFC 2109) CouchDB generates a token that the client can use for the next few requests to CouchDB. Tokens are valid until a timeout. When CouchDB sees a valid token in a subsequent request, it will authenticate the user by this token without requesting the password again. By default, cookies are valid for 10 minutes, but it’s adjustable. Also it’s possible to make cookies persistent.

To obtain the first token and thus authenticate a user for the first time, the username and password must be sent to the _session API.

1.2.21.2.1. /_session

POST /_session

Initiates new session for specified user credentials by providing Cookie value.

Request Headers:
 
  • Content-Type
    • application/x-www-form-urlencoded
    • application/json
Query Parameters:
 
  • next (string) – Enforces redirect after successful login to the specified location. This location is relative from server root. Optional.
Form Parameters:
 
  • name – User name
  • password – Password
Response Headers:
 
Response JSON Object:
 
  • ok (boolean) – Operation status
  • name (string) – Username
  • roles (array) – List of user roles
Status Codes:

Request:

  1. POST /_session HTTP/1.1
  2. Accept: application/json
  3. Content-Length: 24
  4. Content-Type: application/x-www-form-urlencoded
  5. Host: localhost:5984
  6. name=root&password=relax

It’s also possible to send data as JSON:

  1. POST /_session HTTP/1.1
  2. Accept: application/json
  3. Content-Length: 37
  4. Content-Type: application/json
  5. Host: localhost:5984
  6. {
  7. "name": "root",
  8. "password": "relax"
  9. }

Response:

  1. HTTP/1.1 200 OK
  2. Cache-Control: must-revalidate
  3. Content-Length: 43
  4. Content-Type: application/json
  5. Date: Mon, 03 Dec 2012 01:23:14 GMT
  6. Server: CouchDB (Erlang/OTP)
  7. Set-Cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/; HttpOnly
  8. {"ok":true,"name":"root","roles":["_admin"]}

If next query parameter was provided the response will trigger redirection to the specified location in case of successful authentication:

Request:

  1. POST /_session?next=/blog/_design/sofa/_rewrite/recent-posts HTTP/1.1
  2. Accept: application/json
  3. Content-Type: application/x-www-form-urlencoded
  4. Host: localhost:5984
  5. name=root&password=relax

Response:

  1. HTTP/1.1 302 Moved Temporarily
  2. Cache-Control: must-revalidate
  3. Content-Length: 43
  4. Content-Type: application/json
  5. Date: Mon, 03 Dec 2012 01:32:46 GMT
  6. Location: http://localhost:5984/blog/_design/sofa/_rewrite/recent-posts
  7. Server: CouchDB (Erlang/OTP)
  8. Set-Cookie: AuthSession=cm9vdDo1MEJDMDEzRTp7Vu5GKCkTxTVxwXbpXsBARQWnhQ; Version=1; Path=/; HttpOnly
  9. {"ok":true,"name":null,"roles":["_admin"]}

GET /_session

Returns information about the authenticated user, including a User Context Object, the authentication method and database that were used, and a list of configured authentication handlers on the server.

Query Parameters:
 
  • basic (boolean) – Accept Basic Auth by requesting this resource. Optional.
Response JSON Object:
 
  • ok (boolean) – Operation status
  • userCtx (object) – User context for the current user
  • info (object) – Server authentication configuration
Status Codes:

Request:

  1. GET /_session HTTP/1.1
  2. Host: localhost:5984
  3. Accept: application/json
  4. Cookie: AuthSession=cm9vdDo1MEJDMDQxRDpqb-Ta9QfP9hpdPjHLxNTKg_Hf9w

Response:

  1. HTTP/1.1 200 OK
  2. Cache-Control: must-revalidate
  3. Content-Length: 175
  4. Content-Type: application/json
  5. Date: Fri, 09 Aug 2013 20:27:45 GMT
  6. Server: CouchDB (Erlang/OTP)
  7. Set-Cookie: AuthSession=cm9vdDo1MjA1NTBDMTqmX2qKt1KDR--GUC80DQ6-Ew_XIw; Version=1; Path=/; HttpOnly
  8. {
  9. "info": {
  10. "authenticated": "cookie",
  11. "authentication_db": "_users",
  12. "authentication_handlers": [
  13. "cookie",
  14. "default"
  15. ]
  16. },
  17. "ok": true,
  18. "userCtx": {
  19. "name": "root",
  20. "roles": [
  21. "_admin"
  22. ]
  23. }
  24. }

DELETE /_session

Closes user’s session by instructing the browser to clear the cookie. This does not invalidate the session from the server’s perspective, as there is no way to do this because CouchDB cookies are stateless. This means calling this endpoint is purely optional from a client perspective, and it does not protect against theft of a session cookie.

Status Codes:
  • 200 OK – Successfully close session.

Request:

  1. DELETE /_session HTTP/1.1
  2. Accept: application/json
  3. Cookie: AuthSession=cm9vdDo1MjA1NEVGMDo1QXNQkqC_0Qmgrk8Fw61_AzDeXw
  4. Host: localhost:5984

Response:

  1. HTTP/1.1 200 OK
  2. Cache-Control: must-revalidate
  3. Content-Length: 12
  4. Content-Type: application/json
  5. Date: Fri, 09 Aug 2013 20:30:12 GMT
  6. Server: CouchDB (Erlang/OTP)
  7. Set-Cookie: AuthSession=; Version=1; Path=/; HttpOnly
  8. {
  9. "ok": true
  10. }

1.2.21.3. Proxy Authentication

Proxy authentication is very useful in case your application already uses some external authentication service and you don’t want to duplicate users and their roles in CouchDB.

This authentication method allows creation of a User Context Object for remotely authenticated user. By default, the client just needs to pass specific headers to CouchDB with related requests:

Request:

  1. GET /_session HTTP/1.1
  2. Host: localhost:5984
  3. Accept: application/json
  4. Content-Type: application/json; charset=utf-8
  5. X-Auth-CouchDB-Roles: users,blogger
  6. X-Auth-CouchDB-UserName: foo

Response:

  1. HTTP/1.1 200 OK
  2. Cache-Control: must-revalidate
  3. Content-Length: 190
  4. Content-Type: application/json
  5. Date: Fri, 14 Jun 2013 10:16:03 GMT
  6. Server: CouchDB (Erlang/OTP)
  7. {
  8. "info": {
  9. "authenticated": "proxy",
  10. "authentication_db": "_users",
  11. "authentication_handlers": [
  12. "cookie",
  13. "proxy",
  14. "default"
  15. ]
  16. },
  17. "ok": true,
  18. "userCtx": {
  19. "name": "foo",
  20. "roles": [
  21. "users",
  22. "blogger"
  23. ]
  24. }
  25. }

Note that you don’t need to request session to be authenticated by this method if all required HTTP headers are provided.

1.2.21.4. JWT Authentication

JWT authentication enables CouchDB to use externally-generated JWT tokens instead of defining users or roles in the _users database.

The JWT authentication handler requires that all JWT tokens are signed by a key that CouchDB has been configured to trust (there is no support for JWT’s “NONE” algorithm).

Additionally, CouchDB can be configured to reject JWT tokens that are missing a configurable set of claims (e.g, a CouchDB administrator could insist on the exp claim).

All claims presented in a JWT token are validated if presented, regardless of whether they are required.

Two sections of config exist to configure JWT authentication;

The required_claims config setting is a comma-separated list of additional mandatory JWT claims that must be present in any presented JWT token. A :code 400:Bad Request is sent if any are missing.

The alg claim is mandatory as it used to lookup the correct key for verifying the signature.

The sub claim is mandatory and is used as the CouchDB user’s name if the JWT token is valid.

A private claim called _couchdb.roles is optional. If presented, as a JSON array of strings, it is used as the CouchDB user’s roles list as long as the JWT token is valid.

  1. ; [jwt_keys]
  2. ; Configure at least one key here if using the JWT auth handler.
  3. ; If your JWT tokens do not include a "kid" attribute, use "_default"
  4. ; as the config key, otherwise use the kid as the config key.
  5. ; Examples
  6. ; hmac:_default = aGVsbG8=
  7. ; hmac:foo = aGVsbG8=
  8. ; The config values can represent symmetric and asymmetrics keys.
  9. ; For symmetrics keys, the value is base64 encoded;
  10. ; hmac:_default = aGVsbG8= # base64-encoded form of "hello"
  11. ; For asymmetric keys, the value is the PEM encoding of the public
  12. ; key with newlines replaced with the escape sequence \n.
  13. ; rsa:foo = -----BEGIN PUBLIC KEY-----\nMIIBIjAN...IDAQAB\n-----END PUBLIC KEY-----\n
  14. ; ec:bar = -----BEGIN PUBLIC KEY-----\nMHYwEAYHK...AzztRs\n-----END PUBLIC KEY-----\n

The jwt_key section lists all the keys that this CouchDB server trusts. You should ensure that all nodes of your cluster have the same list.

JWT tokens that do not include a kid claim will be validated against the $alg:_default key.

It is mandatory to specify the algorithm associated with every key for security reasons (notably presenting a HMAC-signed token using an RSA or EC public key that the server trusts: https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/).

Request:

  1. GET /_session HTTP/1.1
  2. Host: localhost:5984
  3. Accept: application/json
  4. Content-Type: application/json; charset=utf-8
  5. Authorization: Bearer <JWT token>

Response:

  1. HTTP/1.1 200 OK
  2. Cache-Control: must-revalidate
  3. Content-Length: 188
  4. Content-Type: application/json
  5. Date: Sun, 19 Apr 2020 08:29:15 GMT
  6. Server: CouchDB (Erlang/OTP)
  7. {
  8. "info": {
  9. "authenticated": "jwt",
  10. "authentication_db": "_users",
  11. "authentication_handlers": [
  12. "cookie",
  13. "proxy",
  14. "default"
  15. ]
  16. },
  17. "ok": true,
  18. "userCtx": {
  19. "name": "foo",
  20. "roles": [
  21. "users",
  22. "blogger"
  23. ]
  24. }
  25. }

Note that you don’t need to request session to be authenticated by this method if the required HTTP header is provided.