AUTHENTICATION Service

This core service manages the authentication of users and applications for the access to services within the yuuvis® Momentum cluster.

Table of Contents

Characteristics

Service Nameauthentication
Port Range80
Profilesprod,oauth2,kubernetes,metrics
Helm Chartyuuvis
Internal APIAUTHENTICATION Service Endpoints

Function

The yuuvis® authentication service decides for each API request of any user if the access is granted or not. In its configuration, the access conditions can be defined individually for each API endpoint. Thus, permissions in yuuvis® Momentum can be set not only for types of actions and the usage of specific object types, but also directly for API endpoints. It is even possible to allow the usage of an API endpoint for callers without authentication.

Access Authorization for Endpoints

Access permissions can be configured for each endpoint (core API URLs and service URLs) in the yuuvis® API authentication service. For this purpose, endpoint patterns are assigned to access conditions.

For each incoming request, the first condition is determined with an endpoint pattern that matches the request URL. This condition is evaluated and decides whether access is granted or not. Access permissions without access conditions are granted after log in. The requesting client can identify rejected requests by the status code 403 (forbidden).

The access conditions are described in the access attribute of the access permission. User attributes (like user ID, tenant membership or user roles) and request attributes (like IP address or request header) can be used. Complex access conditions can be formed with operators and functions.

By means of the expose flag, endpoints can be made accessible for unauthenticated access. That means that clients can call the endpoint without having to log in first. The access condition for such endpoints can only contain functions for the evaluation of IP addresses and request headers. Access conditions for expose endpoints always have precedence over those with mandatory authentication, even if they are further down in the mapping list. Services that are called via expose endpoints cannot determine the identity of the caller, even if the caller was authenticated by another endpoint. Without the expose flag, access permissions are only granted after authentication.

Access permissions can be limited to specific HTTP methods (method attribute of the access permission). If you omit the specification, then the permission is applied to all HTTP methods. An access permission can contain multiple endpoint patterns and HTTP methods separated by commas.

Access permissions are registered as an authorization.accesses list in the configuration of yuuvis® API authentication-service. If multiple lists are entered, only the last one is applied.

Rules for Endpoint Patterns

  • ? placeholder for exactly one random character
  • * placeholder for exactly one path segment
  • ** placeholder for any number of path segments
  • the query string cannot be included in the pattern

Examples:

  • /com/t?st.html
    • matches com/test.html but also com/tast.html or com/txst.html
  • /com/*.html
    • matches all .html files in the com directory
  • /com/**/test.html
    • matches all test.html files underneath the com path
  • /org/springframework/**/*.html
    • matches all .html files underneath the org/springframework path
  • /org/**/servlet/test.html
    • matches org/springframework/servlet/test.html but also org/springframework/testing/servlet/test.html and org/servlet/test.html

Syntax for Access Conditions

  • operators
    • or, and, () - operators for forming complex access conditions
    • == - compares strings
  • functions for expose endpoints
    • hasIpAddress('<IP range>') - returns true if the request comes from the passed IP address range
    • hasHeader('<header name>', '<value>') - returns true if the request contains the passed header and its value starts with the passed value
  • functions for endpoints with authentication requirement
    • permitAll() - returns true (parentheses can be omitted)
    • denyAll() - returns false (parentheses can be omitted)
    • not(<expression>) - negates passed expression
    • hasIpAddress('<IP-Bereich>') - returns true if the request comes from the passed IP address range
    • principal.getId() - returns caller’s ID
    • principal.getUsername() - returns the login name of the user account (this can occur several times in multi-tenancy systems)
    • principal.getTenant() - returns the caller’s tenant
    • hasAuthority('<user role>') - returns true if the caller has the passed role
    • hasAnyAuthority('<role1>','<role2>',...) - returns true if the caller has one of the passed roles

Combined Examples

Callers from the IP address range 192.168.1.0/24 can access managed endpoints without authentication. All other callers must login and have one of the following roles: EXAMPLE_ADMIN_ROLE or EXAMPLE_INTEGRATOR_ROLE.

authorization.accesses:
  - endpoints: /manage/**,/*/manage/**
    expose: true
    access: hasIpAddress('192.168.1.0/24')
  - endpoints: /manage/**,/*/manage/**
    access: hasAnyAuthority('EXAMPLE_ADMIN_ROLE','EXAMPLE_INTEGRATOR_ROLE')

Endpoints for using the web application are accessible for all authenticated users.

authorization.accesses:
  - endpoints: /api/dms/**,/api-web/**,/api/sandbox/renditions/**


The yuuvis® core API is read-only. access: permitAll can be omitted as it corresponds to the default setting. The prohibition condition for the POST method and DELETE method can also be omitted, because the access to unlisted endpoints is generally denied.

authorization.accesses:
  - endpoints: /api/dms/objects/**
    method: POST,DELETE
    access: denyAll
  - endpoints: /api/dms/objects/**
    method: GET
    access: permitAll
  - endpoints: /api/dms/objects/search/**
    method: POST
    access: permitAll

Only users of the default tenant and dev tenant may use custom services.

authorization.accesses:
  - endpoints: /custom/**
    access: principal.getTenant() == 'default' or principal.getTenant() == 'dev'

Users of the dev tenant are denied access to the custom service. All other users have access.

authorization.accesses:
  - endpoints: /custom/**
    access: not(principal.getTenant() == 'dev')

The user with the ID 78d3b2a8535b has unrestricted document access. All other users only have access to the latest document version.

authorization.accesses:
  - endpoints: /api/dms/objects/*/versions/**
    access: principal.getId() == '78d3b2a8535b'
  - endpoints: /api/dms/objects/**

The users historyTracker of all tenants only have access to the document history. They have no access to other document information. All other users have unrestricted document access.

authorization.accesses:
  - endpoints: /api/dms/objects/*/history
  - endpoints: /api/dms/objects/**
    access: not(principal.getUsername() == 'historyTracker')

Accessing External Services via Authentication Service

The AUTHENTICATION service manages the access to the yuuvis® Momentum API gateway. With a suitable configuration, also the access to external services running in the same Kubernetes cluster can be managed via the AUTHENTICATION service of yuuvis® Momentum.

>> Accessing External Services via AUTHENTICATION Service

Internal JSON Web Tokens

Each call of a yuuvis® Momentum endpoint is routed through the AUTHENTICATION service. After successful authentication, an internal JSON Web Token (JWT) is created and assigned to the call containing user-specific information. This JWT authorizes the call in every service within the data processing chain.

The JWT is assigned to the call via Authorization header.
Note: Depending on the concrete call, multiple headers might be assigned to it (e.g. containing the user's roles). However, the sum of all header sizes must not exceed the overall size limit of 8 KB.

Structure of internal JWTs

The internal JWTs consist of

  • header with signature algorithm RS256,
  • payload and
  • as of 2021 Autumn, a signature of header and payload.

These three parts are included as .-separated Base64-encoded blocks in each authorization request header for API calls, optionally encrypted.

The payload contains key-value pairs specifying the following parameters:

ParameterDescription
subUser ID of the user requesting the API call.
tenantTenant the requesting user belongs to.
nameAccount name of the user.
accessTokenContains the external authentication token taken from the identity provider.
authoritiesA list containing the roles that are assigned to the user.
abac (as of 2023 Summer)Optional: a map with single string keys and a list of strings as value for each key. Allows for attribute-based access control (see example below).
iatIdentifies the time at which the JWT was issued.
expIdentifies the expiration time on and after which the JWT must not be accepted for processing. Numeric date

An example payload is displayed in the code block below (abac section available as of 2023 Summer).

Example JWT Payload
{
    "sub": "3cfaf962-b254-45c8-b0e9-82f79f2c26ee",
    "tenant": "sales-office",
    "name": "mustermann",
    "accessToken": "Bearer eyJhbGciOiJS...",
    "iat": 1621324798,
    "exp": 1621325698,
    "authorities": [
        "YUUVIS_DEFAULT",
        "YUUVIS_MANAGE_SETTINGS",
        "ACCESS_MAILBOXES"
    ],
    "abac": {
      "mailGroups": [
           "mailbox_sales",
           "mailbox_pm"
       ],
       "sap_permissions": [
           "sap_read",
           "sap_write"
       ]
    }
}

Caching User Attributes

Note

As of 2023 Summer, client and BPM components of yuuvis® Momentum do NOT yet support caching user attributes.

The AUTHENTICATION service can be configured to exclude the authorization and abac sections from the JWT. Instead, the full set of user attributes including authorization and abac sections is stored for 5 minutes in a userAttributes Redis cache for each logged-in user.

All services within the yuuvis® Momentum cluster that need the authorization and abac information retrieve them from the userAttributes Redis cache.

Within the cluster, the userAttributes cache is available via Redis CLI:

  • The command

    redis-cli keys 'userAttributes*'


    retrieves a list of all user attributes-related keys for all tenants. Each key contains the tenant und the user ID for a logged-in user. If only one user is currently logged-in, the response could be, e.g.,

    redis-cli keys 'userAttributes*'
    1) "userAttributes::yuuvistest,3cfaf962-b254-45c8-b0e9-82f79f2c26ee"


    • userAttributes is the cache name. It is the same for all keys.
    • yuuvistest is the example tenant name.
    • 3cfaf962-b254-45c8-b0e9-82f79f2c26ee is the example user ID.
  • For each key, the stored value contains the full set of user attributes for the corresponding user. For the example user, it can be retrieved via

    redis-cli get userAttributes::yuuvistest,d90b12d5-1288-4a73-92fc-d9b6872df812

    The response is a string containing the encoded JSON object, e.g.,

    "\"{\\\"username\\\":\\\"root\\\",\\\"id\\\":\\\"d90b12d5-1288-4a73-92fc-d9b6872df812\\\",\\\"title\\\":\\\"First User\\\",\\\"email\\\":\\\"testroot@yuuvis\\\",\\\"firstname\\\":\\\"First\\\
    ",\\\"lastname\\\":\\\"User\\\",\\\"domain\\\":\\\"dd\\\",\\\"tenant\\\":\\\"yuuvistest\\\",\\\"authorities\\\":[\\\"YUUVIS_DEFAULT\\\",\\\"YUUVIS_SYSTEM_INTEGRATOR\\\",\\\"YUUVIS_TENANT_ADMI
    N\\\"],\\\"accountNonExpired\\\":true,\\\"accountNonLocked\\\":true,\\\"credentialsNonExpired\\\":true,\\\"enabled\\\":true}\""

Furthermore, an internal endpoint of the AUTHENTICATION service GET /session/updateUserAttributeCache/{tenant}/{userId} is available. It can be called by services within the cluster to retrieve user information and refresh the cache in case a logged-in user is missing (e.g., if the maximum item storage time of 5 minutes is exceeded).

To activate the userAttributes cache, the following points have to be considered:

  • The authorization.cacheUserAttributes parameter has to be configured to true in the authentication-prod.yml configuration file.
  • All services that need authorization and abac information require the redis profile. This applies to the following core services:
    • API gateway
    • AUDIT service
    • AUTHENTICATION service
    • INDEX service
    • REGISTRY service
    • REPOSITORY service
    • SEARCH service
    • SYSTEM service
  • Custom services that might run within the yuuvis® Momentum cluster can retrieve authorization and abac information from Redis or via the endpoint GET /session/updateUserAttributeCache/{tenant}/{userId} if necessary.

Validation of internal JWTs

In order to prevent unauthorized access from outside by faking the JWT, its signature can be used for an additional validation of the caller's authorization.  As of version 2022 Spring, the expiration date is validated as well. Thus, it is not possible to authenticate with a token anymore if its expiration date is exceeded. The validation is provided by the internal endpoint /jwt/verify of the AUTHENTICATION Service.
>> GET /jwt/verify

To activate the validation, follow the link below.
>> Validating Internal JSON Web Tokens

Running Multiple Instances

As of version 2022 Spring:

As the number of users increases, more instances may be started for the AUTHENTICATION service to maintain performance. To ensure that the session status of logged-in users is available to all instances, it is stored centrally in a Redis database. This way, users do not have to log in again after a temporary system failure. Their respective service state is stored in a Redis database, and is retrieved by the system after all instances are restarted. The users' session states remain in the Redis database until the sessions have expired or are removed by the users' logging off. If an instance of the AUTHENTICATION service is unavailable for any reason, an instance running in parallel can take over without the user having to log in again. In this way, the AUTHENTICATION service is both fail-safe and scalable.

To allow the storage of individual user session states in the designated Redis database, follow these steps to modify the AUTHENTICATION service configuration:

  • Extend the authentication-prod.yml configuration file by the following lines:

    spring.session.store-type: redis
    management.health.redis.enabled: true
  • Add the redis profile to the AUTHENTICATION service:

    • Run the command:
      kubectl -n yuuvis edit deploy authentication
    • Extend the SPRING_PROFILES_ACTIVE environment variable with redis.
  • Restart all instances of the AUTHENTICATION service.
    • For example, instance 2 can be restarted using the following command:

      kubectl -n yuuvis scale deploy authentication --replicas=2

Embedding in an External Web Page as iframe

Create an Ingress for HTTPS that enables access to all resources for the tenant selection page via Content-Security-Policy-Header.

nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Content-Security-Policy "frame-ancestors 'self' http://portal.org/ http://portal.org:*/; style-src 'self' 'unsafe-inline' https://unpkg.com/ https://fonts.googleapis.com/; font-src 'self' 'unsafe-inline' https://fonts.gstatic.com/;" always;
  • For embedding a client application, further configuration might be necessary.
  • Replace portal.org by your custom URL of the external web page.
  • The tenant selection page loads further resources from https://unpkg.com/ and https://fonts.googleapis.com/.

Configure your identity provider for the access via iframe (Example: Keycloak iframe configuration).Configure the following parameters in the authentication-prod.yml configuration file:

server.servlet.session.cookie.same-site: 'None'
server.servlet.session.cookie.secure: true

Refresh the CONFIGSERVICE

Restart the AUTHENTICATION service.

Configuration

The yuuvis® Momentum configuration files for the operation in the Kubernetes cluster are stored on the Git Server configured in the system. In order to change the configuration of a service, you need to access the Git repository. 

Parameters in Profiles

The following parameters are referenced from the corresponding profiles. Click a profile in order to display descriptions and default values of the corresponding parameters.

ProfileParameter
application-oauth2.ymlkeycloak.host
authentication.oauth2.tenants
authentication-prod.ymlrouting.defaultEntryPoint
management.endpoints
management.endpoint
routing.endpoints
authorization.accesses
spring.session.store-type (as of 2022 Spring)
management.health.redis.enabled (as of 2022 Spring)

The values for the parameters can be modified as described here.
>> Configuring Services using Profiles.


Read on

application-oauth2.yml

Parameters of the general oauth2 profile available to all services. Keep reading

Configuring Services using Profiles

This article explains the usage of service profiles in yuuvis® Momentumhow to add and use custom profiles. Keep reading