Authentication
Atoti UI authenticates all its HTTP requests to Atoti Server and the content server with a JWT. It also authenticates the opening of a WebSocket against Atoti Server in order to perform real-time MDX queries, using a cookie.
This page describes how Atoti UI retrieves the JWT and cookie by default. This flow depends on whether Atoti UI is served by the JWT server itself, or by a remote web server.
Atoti UI works with any authentication scheme by default. You can use it off-the-shelf, independently from whether you use a login form, LDAP, OIDC, Kerberos, etc. on the server side.
Server requirements
There are requirements on the server side for users to be able to authenticate on Atoti UI:
- One of your servers must expose a
jwt
service returning the JWT when receiving aGET
request carrying the valid session cookie of an authenticated user. This server is referred to as the JWT server throughout the documentation and it is typically the content server, although it can also be one of the Atoti servers.
You can configure the URL and version of this server through the jwtServer
property in your Atoti UI env.js
file.
- The JWT must be shared by all servers: Atoti UI authenticates once against the JWT server, and is then able to communicate with all servers.
- Each Atoti server in the solution must expose a
ping
endpoint, which responds with apong
success message and sets a cookie upon receiving aGET
request authenticated with the JWT. This is necessary for Atoti UI to open WebSockets.
Embedded Atoti UI
In this scenario, the Atoti UI assets are served directly by the JWT server, and they are protected by its security filters.
This is the recommended way of serving Atoti UI, as this significantly simplifies the configuration (CORS, cookie security, etc.) and authentication flow (server redirection logic, number of network roundtrips, loading of Atoti UI assets, etc.).
Login
For example, let's assume that the content server is configured to be the JWT server and to serve Atoti UI at path /ui/index.html
The authentication flow goes as follows:
- The user visits
contentServerUrl/ui/index.html
in their browser. From there, two things can happen:- The user is already logged in: a valid session cookie is already set in the browser for the content server. In that case:
- Atoti UI's
index.html
is loaded, and its JavaScript is run. - A request is made to the
/jwt
service of the JWT server (= content server in this case) in order to retrieve the JWT, authenticated thanks to the session cookie. - The JWT server responds with a status code 200 and a JWT.
- This JWT is used in all further requests to all servers (including the Atoti servers and the content server defined in
env.js
).
- Atoti UI's
- The user is not logged in: no session cookie is set, or it is invalid. In that case:
- The server redirects the user to
/login
. - Upon successful login, the server redirects to
/ui/index.html
. - Atoti UI's
index.html
is loaded, and its JavaScript is run (see above).
- The server redirects the user to
- The user is already logged in: a valid session cookie is already set in the browser for the content server. In that case:
Logout
When the user logs out from Atoti UI, its JavaScript navigates to the /logout
page of the JWT server, and sends a POST /logout
request to all other Atoti servers and the content server.
Here is a sequence diagram to illustrate this, where the content server is configured to be the JWT server and to serve Atoti UI.
Remote Atoti UI
Additional server requirements
Serving Atoti UI from a remote web server adds the following constraints on the JWT server:
- An unauthenticated call to the
/jwt
service must yield a 401. - Upon successfully authenticating on
/login?redirectUrl=myAtotiUIUrl
, the server must redirect tomyAtotiUIUrl
, with a session cookie set forjwtServer
.
Login
The login flow then goes as follows:
- When Atoti UI's JavaScript is run, a request is made to the
/jwt
service of the JWT server in order to retrieve the JWT. From there, two things can happen:- The user is already logged in: a valid session cookie is already set in the browser for the JWT server. In that case:
- The JWT server responds with a status code 200 and a JWT.
- This JWT is used in all further requests to all servers (including the Atoti servers and the content server defined in
env.js
).
- The user is not logged in: no session cookie is set, or it is invalid. In that case:
- The JWT server responds with a 401 status code.
- Upon receiving it, Atoti UI redirects the user to the
/login
page of the JWT server, with theredirectUrl
search parameter set to the current URL (where the user accessed Atoti UI). - Upon successful login, the JWT server redirects the user to Atoti UI (thanks to the
redirectUrl
search parameter) with a valid session cookie for the JWT server. - Atoti UI sends a request to the
/jwt
service again, which is successful this time thanks to the cookie (see above).
- The user is already logged in: a valid session cookie is already set in the browser for the JWT server. In that case:
Here is a sequence diagram to illustrate this flow, where the content server is configured to be the JWT server.
Notice how this is more complex than the embedded setup. On top of the additional constraints on the server and the added network roundtrips, you will potentially have to configure CORS and handle third-party cookies if you deploy your UI and server on different domains. In particular, note that third-party cookies are deprecated or blocked by default in most major browsers.
Logout
This is the same as in the embedded case.
Websockets
As illustrated in the diagrams above, Atoti UI securely opens a WebSocket against each Atoti server it is connected to.
Since in the WebSocket protocol HTTP headers cannot be passed in the opening handshake, and in particular the JWT cannot be passed as an Authorization
header, Atoti UI authenticates the WebSocket through a cookie instead.
To obtain this cookie before actually opening the WebSocket, Atoti UI first makes a request on the Atoti server's ping
endpoint, authenticated with the JWT.
If the JWT is valid, Atoti Server responds with a pong
success message which sets a cookie in the user's browser for this server.
Note that:
- This cookie must not be confused with the session cookie associated with the JWT server and allowing the login flow described above (unless the Atoti server itself is used as the JWT server, as opposed to the content server for example).
- Cookies are set by domain, but not by port, so if you deploy several servers at different ports on the same domain in your Atoti solution, you need to use a different cookie name for each server.
Opting out of the default flow - Custom authentication
As described in the sections above, Atoti UI works off-the-shelf with any authentication scheme on the server side, without requiring any custom JavaScript code on the client side.
But if you still want to opt out of this default behavior, you can implement a custom authentication flow.
To do so, use your own configuration.higherOrderComponents
instead of withAuthenticatedClientsAndUser
in your Atoti UI extensions.