Skip to content

REST API authentication

This page refers to REST API reference, where you can find detailed information about REST API resources and endpoints.

Five authentication methods are currently supported: session (default), JWT, basic, OAuth and client certificate (SSL).

You can only use one of those methods at the same time.

Using HTTPS for authenticated traffic is highly recommended.

For other security related subjects, see:

SiteAccess login

The anonymous user is used to perform authentification requests. Therefore, the "Anonymous" role must have user/login permission on the SiteAccess that matches the REST domain or is passed through the X-Siteaccess header.

Session-based authentication

This authentication method requires a session cookie to be sent with each request.

If you use this authentication method with a web browser, this session cookie is automatically available as soon as your visitor logs in. Add it as a cookie to your REST requests, and the user will be authenticated.

Sessions are created to re-authenticate the user only (and perform authorization), not to hold session state in the service. Because of that, you can use this method as supporting AJAX-based applications even if it violates the principles of RESTful services.

Configuration

Session is the default method and is already enabled, so no configuration required. Enabling any other method disables session.

Usage examples

You can create a session for a visitor even if they are not logged in by sending the POST request to /user/sessions. To log out, use the DELETE request on the same resource.

Establishing session

Creating session

To create a session, execute the following REST request:

1
2
3
4
POST /user/sessions HTTP/1.1
Host: www.example.net
Accept: application/vnd.ez.api.Session+xml
Content-Type: application/vnd.ez.api.SessionInput+xml
1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<SessionInput>
  <login>admin</login>
  <password>publish</password>
</SessionInput>
1
2
3
4
HTTP/1.1 201 Created
Location: /user/sessions/go327ij2cirpo59pb6rrv2a4el2
Set-Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2; domain=.example.net; path=/; expires=Wed, 13-Jan-2021 22:23:01 GMT; HttpOnly
Content-Type: application/vnd.ez.api.Session+xml
1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<Session href="/user/sessions/sessionID" media-type="application/vnd.ez.api.Session+xml">
  <name>eZSESSID98defd6ee70dfb1dea416</name>
  <identifier>go327ij2cirpo59pb6rrv2a4el2</identifier>
  <csrfToken>23lk.neri34ijajedfw39orj-3j93</csrfToken>
  <User href="/user/users/14" media-type="vnd.ez.api.User+xml"/>
</Session>
1
2
3
4
POST /user/sessions HTTP/1.1
Host: www.example.net
Accept: application/vnd.ez.api.Session+json
Content-Type: application/vnd.ez.api.SessionInput+json
1
2
3
4
5
6
{
  "SessionInput": {
    "login": "admin",
    "password": "publish"
  }
}
1
2
3
4
HTTP/1.1 201 Created
Location: /user/sessions/go327ij2cirpo59pb6rrv2a4el2
Set-Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2; domain=.example.net; path=/; expires=Wed, 13-Jan-2021 22:23:01 GMT; HttpOnly
Content-Type: application/vnd.ez.api.Session+xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "Session": {
    "_media-type": "application\/vnd.ez.api.Session+json",
    "_href": "\/api\/ibexa\/v2\/user\/sessions\/jg1nhinvepsb9ivd10hbjbdp4l",
    "name": "eZSESSID98defd6ee70dfb1dea416",
    "identifier": "go327ij2cirpo59pb6rrv2a4el2",
    "csrfToken": "23lk.neri34ijajedfw39orj-3j93",
    "User": {
      "_media-type": "application\/vnd.ez.api.User+json",
      "_href": "\/api\/ibexa\/v2\/user\/users\/14"
    }
  }
}
Logging in with active session

Logging in is very similar to session creation, with one important detail: the CSRF token obtained in the previous step is added to the new request through the X-CSRF-Token header.

1
2
3
4
5
6
POST /user/sessions HTTP/1.1
Host: www.example.net
Accept: application/vnd.ez.api.Session+xml
Content-Type: application/vnd.ez.api.SessionInput+xml
Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2
X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93
1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<SessionInput>
  <login>admin</login>
  <password>publish</password>
</SessionInput>
1
2
HTTP/1.1 200 OK
Content-Type: application/vnd.ez.api.Session+xml
1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<Session href="user/sessions/go327ij2cirpo59pb6rrv2a4el2/refresh" media-type="application/vnd.ez.api.Session+xml">
  <name>eZSESSID98defd6ee70dfb1dea416</name>
  <identifier>go327ij2cirpo59pb6rrv2a4el2</identifier>
  <csrfToken>23lk.neri34ijajedfw39orj-3j93</csrfToken>
  <User href="/user/users/14" media-type="vnd.ez.api.User+xml"/>
</Session>
1
2
3
4
5
6
POST /user/sessions HTTP/1.1
Host: www.example.net
Accept: application/vnd.ez.api.Session+json
Content-Type: application/vnd.ez.api.SessionInput+json
Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2
X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93
1
2
3
4
5
6
{
  "SessionInput": {
    "login": "admin",
    "password": "publish"
  }
}
1
2
HTTP/1.1 200 OK
Content-Type: application/vnd.ez.api.Session+json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "Session": {
    "_media-type": "application\/vnd.ez.api.Session+json",
    "_href": "\/api\/ibexa\/v2\/user\/sessions\/jg1nhinvepsb9ivd10hbjbdp4l",
    "name": "eZSESSID98defd6ee70dfb1dea416",
    "identifier": "go327ij2cirpo59pb6rrv2a4el2",
    "csrfToken": "23lk.neri34ijajedfw39orj-3j93",
    "User": {
      "_media-type": "application\/vnd.ez.api.User+json",
      "_href": "\/api\/ibexa\/v2\/user\/users\/14"
    }
  }
}

Using session

You can now add the previously set cookie to requests to be executed with the logged-in user.

1
2
3
4
GET /content/locations/1/5 HTTP/1.1
Host: www.example.net
Accept: Accept: application/vnd.ez.api.Location+xml
Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2
CSRF token

It can be important to keep the CSRF token (csrfToken) for the duration of the session, because you must send this token in every request that uses unsafe HTTP methods (others than the safe GET or HEAD or OPTIONS) when a session has been established. It should be sent with an X-CSRF-Token header.

Only three built-in routes can accept unsafe methods without CSRF, the sessions routes starting with /user/sessions to create, refresh or delete a session.

1
2
3
4
DELETE /content/types/32 HTTP/1.1
Host: www.example.net
Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2
X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93

If an unsafe request is missing the CSRF token, or the token has incorrect value, an error is returned: 401 Unauthorized.

Rich client application security concerns

The purpose of CSRF protection is to prevent users from accidentally running harmful operations by being tricked into executing an HTTP(S) request against a web applications they are logged into. In browsers this action will be blocked by lack of CSRF token.

However, if you develop a rich client application (JavaScript, JAVA, iOS, Android, etc.), that is:

  • Registering itself as a protocol handler:
    • Exposes unsafe methods in any way
  • Authenticates using either:
    • Session-based authentication
    • "Client side session" by remembering user login/password

Then, you have to make sure to confirm with the user if they want to perform an unsafe operation.

Example:

A rich JavaScript/web application is using navigator.registerProtocolHandler() to register "web+ez:" links to go against REST API. It uses a session-based authentication, and it is in widespread use across the net, or/and it is used by everyone within a company. A person with minimal insight into this application and the company can easily send out the following link to all employees in that company in email: <a href="web+ez:DELETE /content/locations/1/2">latest reports</a>.

Logging out from session

To log out is to DELETE the session using its ID (like in the cookie). As this is an unsafe method, the CSRF token must be presented.

1
2
3
4
DELETE /user/sessions/go327ij2cirpo59pb6rrv2a4el2 HTTP/1.1
Host: www.example.net
Cookie: eZSESSID98defd6ee70dfb1dea416=go327ij2cirpo59pb6rrv2a4el2
X-CSRF-Token: 23lk.neri34ijajedfw39orj-3j93

JWT authentication

Configuration

See JWT authentication to lear how to enable JWT for REST and/or GraphQL.

Usage example

After you configure JWT authentication at least for REST, you can get the JWT token through the following request:

1
2
3
4
POST /user/token/jwt HTTP/1.1
Host: <yourdomain>
Accept: application/vnd.ez.api.JWT+xml
Content-Type: application/vnd.ez.api.JWTInput+xml

Provide the username and password in the request body:

1
2
3
4
<JWTInput>
    <username>admin</username>
    <password>publish</password>
</JWTInput>

If credentials are valid, the server response contains a token:

1
<JWT media-type="application/vnd.ez.api.JWT+xml" token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg"/>

You can then use this token in your request instead of username and password.

1
2
3
4
GET /content/locations/1/5/children
Host: <yourdomain>
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg
Accept: application/vnd.ez.api.LocationList+xml
1
2
3
4
POST /user/token/jwt HTTP/1.1
Host: <yourdomain>
Accept: application/vnd.ez.api.JWT+json
Content-Type: application/vnd.ez.api.JWTInput+json

Provide the username and password in the request body:

1
2
3
4
5
6
{
    "JWTInput": {
        "username": "admin",
        "password": "publish"
    }
}

If credentials are valid, the server response contains a token:

1
2
3
4
5
6
{
    "JWT": {
        "_media-type": "application/vnd.ez.api.JWT+xml",
        "_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg"
    }
}

You can then use this token in your request instead of username and password.

1
2
3
4
GET /content/locations/1/5/children
Host: <yourdomain>
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…-QBE4-6eKNjg
Accept: application/vnd.ez.api.LocationList+json

HTTP basic authentication

For more information, see HTTP Authentication: Basic and Digest Access Authentication.

Configuration

If the installation has a dedicated host for REST, you can enable HTTP basic authentication only on this host by setting a firewall like in the following example before the ibexa_front one:

1
2
3
4
        ibexa_rest:
            host: ^api\.example\.com$
            http_basic:
                realm: Ibexa DXP REST API

Back Office uses REST API

Back Office uses the REST API too (for some parts like the Location tree or the Calendar) on its own domain.

  • If the Back Office SiteAccess matches //admin.example.com (through Map\Host, HostElement or HostText), it calls the REST API under //admin.example.com/api/ezp/v2;
  • If the Back Office SiteAccess matches //localhost/admin (through URIElement, Map\URI or Regex\URI), it calls the REST API under //localhost/api/ezp/v2 because SiteAccess matching with REST isn't enabled at URL level.

If you enable basic authentication for pattern: ^/api/ibexa/v2 to use it in your front office across both production and development environments, your development environment's Back Office won't work correctly. This Back Office tries to access REST through the same URL as the front office. Even when logged in Back Office and using the X-SiteAccess header, the firewall blocks access to REST as you're not logged through basic authentification. Therefore, some Back Office features don't work.

If basic authentication is used only for REST API, it's better to have a dedicated domain even on a development environment. For example, map an api.localhost in your hosts file and set the firewall for host: ^api\.(example\.com|localhost)$.

Usage example

Basic authentication requires the username and password to be sent (username:password), base64 encoded, with each request. For details, see RFC 2617.

Most HTTP client libraries as well as REST libraries support this method. Creating content with binary attachments has an example using basic authentication with cURL and its CURLOPT_USERPWD.

Raw HTTP request with basic authentication

1
2
3
4
GET / HTTP/1.1
Host: api.example.com
Accept: application/vnd.ez.api.Root+json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

OAuth

For more information, see OAuth 2.0 protocol for authorization.

SSL client authentication

The REST API provides authentication of a user by a subject in a client certificate delivered by the web server configured as SSL endpoint.