Table of Contents

Security

Table of Contents

Dictionary terms

API authentication

API access requires the user to be authenticated, excluding a few public endpoints. We can divide the sign in into two parts:

Authentication

Authentication is realized through a request filterchain. The filters must always follow specified behaviour:

In reality there is only one authentication servlet filter - AuthenticationFilter. Others filters are Spring beans implementing IdmAuthenticationFilter interface. An exception in filters is the ExtendExpirationFilter, which is another servlet filter handling the extension of expiration date of JWT tokens. This filter also controls possible exceptions in authentication flow.

API endpoints

There are 2 endpoints for successful user login:

Active filters

Filter do not check authorization or user's permissions, just validate the request data, transform these and pass them to Authentication Managers. There are following filters in IdM core (the core module):

Authorization and JWT token

User authorization is checked on the API endpoint layer and enforced by Spring Security. The permissions are a part of IdM JWT:

All IdM JWT tokens are signed using HMAC256 algorithm. The symmetric encryption key is configuration property of CzechIdM, stored as "idm.sec.security.jwt.secret.token". Default expiration time is 10 minutes.

Backend of CzechIdM supports immediate detection of user's authorization change. Each modification type is implemented as application event processor, for further details please check the source code and tests :) The information about last authority change is kept in IdmAuthorityChange entity. Types of modifications:

Token expiration extension

By default both frontend (FE) and backend (BE) automatically extend the expiration of IdM JWT. In case of successful GET request on API, the token expiration is extended on BE and passed in HTTP response (watch out for CORS, has to be explicitly allowed, since the HTTP header is called "CIDMST"). FE (RestApiService.js) automatically disassembles the response looking for auth. token. If token is present, it is set as new token which shall be used for new API requests (done in App.js).

Developer tip: do not trust the console, especially while working with promises:

static printHeadersOK(response) {
  console.log(response.headers.get('CIDMST')); prints header value
}

static printHeadersWRONG(response) {
  console.log(response.headers); // prints '{}', object looks empty
}

SSO

SSO support on FE is realized by issuing the internal IdM JWT without the need to type in user's credentials. This is done by sending a "prerequest" onto secured /authentication/remote-auth endpoint, accessible only to authenticated users. The authentication itself must be done in one of auth filters.

We expect either HTTP header or Cookie to be the bearer of the remote authentication data. When the user accesses IdM, FE first tries to sign him in using the remote-auth. The remote-auth attempt is done only on first access to CzechIdM, token expiration, authority change or user login.