ADEQUATE : Authentication and authorization

From a web client perspective

The web client uses Satellizer library (https://github.com/sahat/satellizer) to support server security demands where the parties agreed on use of tokens adhering to the JWT standard.

Signing up

  1. User creates a new account by providing relevant information, such as e-mail, by which his or her account will be identified.
  2. The web client sends a request to the server with the relevant information (e-mail, password).
  3. In case no other account is paired with the provided e-mail address, the server creates the new account and responds with an affirmative message. The server additionally asynchronously sends an e-mail to the provided address.
  4. The web client informs the user to await an e-mail with additional instructions.
  5. The e-mail consists (besides human readable instructions) of a hyperlink leading to a specific URL, as configured in the previously mentioned config/sti.properties file. For example, http://localhost:8080/index.html#/signup/<token>, where "<token>" is an actual token provided by the server.
  6. By clicking on the link, the user is redirected to a specific screen on the web client. There, the application automatically parses the URL and sends a confirmation request to the server with the token attached.
  7. If the token has not expired yet, the server responds with an affirmative message, to which the client application responds by displaying information to the user, ensuring him or her the account has been successfully activated, and requesting him or her to log in.

Logging in

  1. The user logs in by providing the e-mail address his or her account is now associated with, and the password.
  2. The application sends a request to the server containing the e-mail and the password.
  3. If the account information is valid, the server responds with an affirmative message with a token attached.
  4. The application saves the token in the user's local storage (by using HTML5 Web Storage API).
  5. From now on, each request the application sends is automatically attached with an authorization header containing the token.
  6. If the user logs out, the token is removed from the local storage.
  7. A server may respond to a request with a negative message, even if the token is provided in the authorization header of the request (e.g. when the token is expired). In that case, the application redirects the user to "log in" screen, where it automatically re-evaluates the validity of the token (by sending a testing request to the server). If the token is not valid anymore, the user is automatically logged out and the token removed from the local storage. The user may log in again.

Because the communication between the web client and the server is still vulnerable to the "man-in-the-middle" attacks, a usage of TLS/SSL communication protocol is highly recommended.

Also the confirmation emails can be turned off in the main configuration.

From the server perspective

Tokens

Employing JWT tokens to authenticate the client of the REST API has several appealing properties, such as:

  • They can be shared with 3rd parties to enable them to act on behalf of the user without compromising the actual credentials (e-mail and password combination).
  • They can carry useful information which does not have to be remembered by the server, but still can be relied on.
    • But it is good to keep in mind that unless other measures are taken, these pieces of information are publicly visible!
    • For example Odalic server stores the date of expiration in the tokens, which is checked by the server, without the fear that it has been tampered with.
  • Unless they are long-lived enough to endanger the user, the server does not have remember which tokens were issued.
    • Unfortunately the processing of tasks may take a long time, during which the client polls the server and it would be impractical to negotiate a new token. So the Odalic server does remember which tokens were issued (their ID is enough). Only then it can revoke them when needed, which is implemented by letting the user change his or her password.
  • They can be safely shared in a URL, unless they are excessively long, because they are composed from safe characters.
    • This is useful in the case of e-mail confirmation, because the token can be placed in the link itself.
  • They are well supported across languages and platforms.

The server uses the auth0 Java JWT library to issue and verify sign-up and password reset tokens and the tokens authenticating the source of the API calls. As the available memory is always limited, only a certain amount of tokens is remembered by the server, when this limit is reached, the oldest issued token is lost.

Authentication and authorization with Jersey

To secure REST endpoints, the privileged Resource classes or their methods (if higher granularity is needed) are marked with cz.cuni.mff.xrg.odalic.api.rest.Secured annotation, which triggers checking code in Authentication request filter. This code calls upon the cz.cuni.mff.xrg.odalic.users.UserService to match the token received in HTTP Authorization header with some of the valid issued ones. The Secured annotation also has a parameter which allows to specify which role the user must have to access the secured endpoint. This is handled by Authorization request filter which compares the callee's role with the set of acceptable ones. Should any of these checks fail, an exception is thrown and mapped to appropriate HTTP response, thus denying the access. So far only two roles are supported: common users and the administrator. The administrator has all the rights of the regular users, plus it can access endpoints allowing to list all the users and delete some of them. Also he or she can act on behalf of another user by providing his or her user ID in the calls.

Password handling

The password set during the sign-up or reset is never stored. The server only computes a hash from it and the assigned salt and compares is with a password sent in login credentials. For this an Scrypt implementation in pure Java was used. It may lack the raw performance, but does not need to be linked to a C library.