Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Excerpt

Description of how client application login to the eHealth Infrastructure.

Table of Contents
maxLevel7
minLevel1

Introduction

Before a client system can connect with the eHealth Infrastructure, several steps must be followed:

  1. The client application for the eHealth Infrastructure must implement an OpenID Connect "code flow" to log in

...

  1. and

...

  1. obtain a set of tokens.

...

  1. The client application needs to be created and configured in the eHealth login server

...

  1. (KeyCloak), given a name, and have its redirection URLs approved and configured in KeyCloak.

  2. Clients can be either confidential (like a server application) or public (like

...

  1. apps or

...

  1. web

...

  1. applications). Confidential clients

...

  1. use a password

...

  1. for authentication, while public clients must use PKCE (pronounced "pixi").

...

  1. You can find more explanations on this topic here and here.

Info

Pay attention to the redirect URLs.

The redirect URLs are the addresses where the client sends its users after they log in, log out, or refresh. These URLs must be approved, specific, and not contain wildcards (*), which could pose a security risk. Examples include the '/login' and '/login-landing' pages where users are redirected after logging in or out. Information on redirect URL.

See Securing Applications and Services Guide (keycloak.org)).

After completing these steps, the Authorization Server (AS) will delegate parts of the login process to other federated servers, but that this is typically transparent for to the client (provided , assuming the login is handled by within a generic standard web browser window that can handle redirects).

Employee logins

For employees it is expected that the total login flow will look somewhat like this. Details can vary depending on the organization of the user (region, municipality or service/support/logistics organization).

Image Removed

Citizen logins (first time)

For citizens, a similar login flow could look like this:

Image Removed

Authorization Server

Unfortunately we don't have the right DNS names for the environments just yet.

But for now an Authorization Server for the inttest environment is available. Its endpoints is described in the contents of this URL: http://a90801479291d11e9865602ac812c206-157159182.eu-west-1.elb.amazonaws.com/auth/realms/inttest/.well-known/openid-configurationmanage redirects.

Client types

There are two main client types: clinical and citizen clients. Each type follows its own login flow and realm, resulting in two authorization URLs (more details in the “Authorization Server” section).

Therefore, if a system handles both clinical and citizen users, its token validation must support multiple certificate URLs.

Here are examples of certificate URLs for the INTTEST environment:

Clinical logins

For clinical client applications, the login flow typically looks like this, although specifics can vary based on the user's organization (region or municipality).

...

Flow for federated clinical (regional or municipality) login

If there's already a session in SEB from the same browser, a single sign-on experience can occur.

Citizen logins (first time)

Citizen login flow may resemble the following:

...

Client systems for citizens initially encounter NemID presented through a federated login service from NemLogin. If the client system supports it, they can store the RT (Request Token) and use it later to resume an authenticated session, based on a PIN code or biometric data. More details can be found in the Key Service overview, which involves selecting a PIN, registering a user/device/PIN via the Key Service, and resuming the session based on stored data by calling the Key Service.

The goal is to offer an alternative, simpler "authentication" method to citizens securely.

Authorization Server Endpoints

Current active environments:

Clinical:

Base URLhttps://saml.${environment}.ehealth.sundhed.dk/auth/realms/ehealth

Citizen:

Base URLhttps://saml.${environment}.ehealth.sundhed.dk/auth/realms/nemlogin

Client Adapters

Keycloak (being the AS) has an extensive set of client adapters (libraries) for usage on various platforms and programming languages:

Example authentication

If, for some reason, you can't use a keycloak client adapter - an example URL for an authentication request using HTTP GET, written in a readable format is shown below. It should be sent as a single line without spaces or new lines.

Authentication request
Code Block
languagebash
 http://saml.inttest.ehealth.sundhed.dk/auth/realms/ehealth/protocol/openid-connect/auth?
  response_type=code&
  client_id=<client_id>&
  redirect_uri=<redirect_uri>&
  scope=openid+profile&
  state=<state>&
  nonce=<nonce>&
  code_challenge=<challenge>&
  code_challenge_method=S256

The parameters have the following meaning:

  • response_type=code – indicates that your server expects to receive an authorization code

  • client_id= – A client ID that is registered on the Authorization Server

  • redirect_uri= – Indicates the URL to return the user to after authorization is complete, such as org.example.app://redirect or a traditional URL for a web app https://app.example.org/redirect.

  • state=1234zyx – A random string generated by your application, which you’ll verify later

  • code_challenge=XXXXXXXXX – The code challenge generated as previously described

  • code_challenge_method=S256 – either plain or S256, depending on whether the challenge is the plain verifier string or the SHA256 hash of the string. If this parameter is omitted, the server will assume plain.

When the authentication is complete, the browser is redirected back to the given "redirect_uri" (which must be whitelisted in the AS) including a "code" as a request parameter. This code must be used when calling the token endpoint afterwards.

Example token exchange

An example of the following POST request to obtain a context-aware access token is shown below.

Authorization code exchange
Code Block
languagebash
POST /auth/realms/ehealth/protocol/openid-connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

  grant_type=refresh_token&
  refresh_token=<refresh_token>&
  client_id=<client_id>&
  client_secret=<client_secret>&
  organization_id=<organization_id>&
  care_team_id=<care_team_id>&
  patient_id=<patient_id>&
  episode_of_care_id=<episode_of_care_id>

The first four parameters are required, and the remaining are optional. 'organization_id' and 'care_team_id' can be used individually or in combination. 'patient_id' and 'episode_of_care_id' can also be used individually or in combination, but requires that 'care_team_id' is also present. More details on context switching can be found at Switching Context.

Use of Access Token

The Access Token is sent as an HTTP header (See https://jwt.io/introduction/ for a further introduction) in all service requests in this form (where "<access token>" is replaced by the specific Access Token):

Code Block
Authorization: Bearer <access token>
Info

Access Tokens and Refresh Tokens are "opaque tokens" but maybe in JWT format. Client systems must not assume this and the format of AT and RT may change without notice.

Determining System Roles Available in the Current Context

The list of system roles available with the currently selected context can be obtained by querying the AS using an HTTP GET with the current Access token at the path /auth/realms/ehealth/protocol/openid-connect/userinfo. The following shows an example request in the realm of eHealth for a clinical user:

User info
Code Block
languagejs
GET https://saml.exttest.ehealth.sundhed.dk/auth/realms/ehealth/protocol/openid-connect/userinfo
Response:
{
    "sub": "...",
    "email_verified": true,
    "cpr": "...",
    "roles": [
        "Service and Logistics",
        "Incident Manager",
        "Report User",
        "Questionnaire Editor",
        "Catalogue Responsible",
        "Clinical Viewer",
        "Care Team Administrator",
        "Clinical Administrator",
        "Catalogue Annotator",
        "Terminology Administrator",
        "Monitoring Adjuster",
        "Citizen Enroller",
        "Monitoring Assistor",
        "Contract Responsible",
        "Order Placer",
        "Incident Reporter",
        "Clinical Supporter"
    ],
    "preferred_username": "...",
    ...
}

The list in “roles” is the KeyCloak role names which can be mapped to system roles by doing a reverse lookup from groups, see https://ehealth-dk.atlassian.net/wiki/spaces/EDTW/pages/270991361/Switching+Context#Mapping-from-Role-to-Privileges.

Logout

To end a session, use end_session_endpoint found in the openid-configuration of the environment (e.g.openid-configuration)

Example:

Logout

Code Block
languagebash
GET /auth/realms/ehealth/protocol/openid-connect/logout HTTP/1.1
Authorization: Bearer <access_token>


You can redirect the browser to /auth/realms/ehealth/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri, which logs you out if you have an SSO session with your browser.