Masterportal
The Masterportal serves as the primary interface for geospatial data visualization and analysis.
7.1. Authentication and Access Control
The optional login for the Masterportal is configured with Keycloak, ensuring secure access. For using the login, the login plugin must be configured during deployment (see documentation for masterportal config.js and config.json). In addition, the masterportal layers must be configured within the portal backend
, i.e., they must be assigned roles that have been defined in keycloak.
After configuration, themes and layers can be filtered based on user roles defined in Keycloak, allowing for tailored user experiences.
In addition, integration of public datasets, such as geojson from open data sources, enhances data availability and visualization capabilities.
7.2. Map Printing
Maps generated within the Masterportal can be printed using Mapfish Print functionality, facilitating the creation of physical copies or PDF exports.
7.3 Backend for Masterportal
The masterportal backend is a small backend that enables the static master portal configuration files to be filtered according to the necessary authorizations and then delivered filtered. The original documentation and source code can be found here: https://gitlab.com/berlintxl/futr-hub/platform/stacks/geodata_stack/portal-backend.
For better readability the important parts regarding the portal are integrated here.
7.3.1.Architecture
The following pictures shows a very high level overview of the used architecture.
7.3.2. Background
The masterportal is a client side http Application, that runs completely in the browser. In the FUTR-HUB project the requirement of roles, that are needed for the displayed content in the portal, came up.
The project decided, to follow the following approach:
- Implement a Login Addon as Addon for the Masterportal. This addon was integrated in the masterportal core in the meantime.
- Implement a backend, that uses the login information to filter the masterportal configuration This backend is described and published in this repository.
7.3.3. Overview
7.3.3.1. Masterportal Login
The Login functionality is implemented as a tool in the masterportal. The code for the tool is part of the masterportal repository, the former addon was integrated in the core.
The login tool supports the OpenID Connect Login with an existing backend. We use Keycloak for this.
The result of the login is, that the current user is authenticated and the OIDC Token is attached to every backend request (for a configurable domain) as Bearer token.
7.3.3.2. Portal Backend
The portal backend runs as a separate service in an own pod on our platform. The configuration files to filter must be provided over the file system.
The backend checks, if a Bearer token is part of the request.
If not: Only the content of an anonymous access role is delivered If yes: All content, with matching roles of the user is delivered (Important: the anonymous roles must be explicitly assigned to the user)
The role names are expected a specific claim in the token.
7.3.3.3. Why this approach?
The implementation approach has the technical advantage, that the masterportal standard code can be used completely as is. The portal is even not aware of the running backend.
7.3.4. Functional Flow in Detail
The flow in total is as shown in the following sequence diagram:
7.3.4.1. Anonymous Access
The steps from 1. to 5. are more or less the masterportal standard load of the page, except the facts, that the three configuration files config.json
, service.json
and rest-service.json
are delivered by the backend. For the portal, the backend acts as a standard webserver.
7.3.4.2. Authenticated Access
In the loaded masterportal, the user clicks "Login" (step 1). With this done, the portal opens a popup and in this popup,the redirect to the IDM (step 2) takes place.
The IDM handles the Authentication with the user. If the Login is successful, the user is redirected back (step 9) to the portal, and the Login Addon extracts a valid Access Token from the flow.
After extracting the token, the portal is reloaded (step 10). The configuration files are requested (step 11) from the backend, too. In this case, the generated token is in the Authorization heade
as a Bearer token.
(If the user is not logged in, the portal reloads as described in the Section "Anonymous Access".)
The backend validates the token (step 12). If the token is valid, the claim with the roles is extracted. After that, the three configuration files are filtered according to the roles.
(the config.json
is partly filtered directly (e.g. for tools)). The "Themetree" is filtered based on the before filtered service.json. Only entries, where the corresponding service configuration is still part of the filtered service.json
are delivered. If folders get empty after the filtering, the folder is also removed.)
The results are returned to the portal (step 13).
The results are rendered by the portal and shown to the user.
7.3.4.3. Configuration and installation
To make this flow working, some configuration tasks are needed in three components.
7.3.4.3.1. Requirements to the IDM
The IDM Configuration needs to following:
Due to the fact, that the masterportal is a browser based application, we created a new client in keycloak for the login process, which needs no authentication from the portal itself.
The client needs to be:
- OpenID Connect Client with type "public access"
- The client must have to correct redicrect URL for your masterportal hosting (We normally use the Base URL of the Masterportal Server with a wildcard at the end of the URL.)
- You need to configure Keycloak roles or groups that can be assigned to users and used for accessing data spaces. (The easiest way is to use the client roles of the new client and assign these to the users)
- Finally you have to configure client scopes, which add the roles as the claim "dataspaces" (can be configured) to the token. In Keycloak this can be done by using a client-role-mapper in the dedicated scopes of the client (add the claim to the access token) The result in the token looks like this:
"given_name": "Andreas",
"family_name": "Linneweber",
"email": "andreas.linneweber@kernblick.de",
"dataspaces": [
"ds_aerial",
"ds_intern",
"ds_nda",
"ds_protected"
]
Make sure this work, before you proceed with the next steps. In Keycloak this can be easily checked by using the Evaluation functions for the client scopes.
7.3.4.3.2. Configuration of the Masterportal
The addon allows the user to login with an OIDC server. The retrieved access token is stored in cookies which can be used by the backend to deliver user-specific data (e.g. layers).
7.3.4.3.2.1. Installation and Configuration
To activate the addon in the masterportal, add the addon to your config.js
as follows:
const Config = {
addons: ["login"],
login: {
oidcAuthorizationEndpoint: "https://idm.DOMAIN.de/auth/realms/REALM/protocol/openid-connect/auth",
oidcTokenEndpoint: "https://idm.DOMAIN.de/auth/realms/REALM/protocol/openid-connect/token",
oidcClientId: "masterportal",
oidcRedirectUri: "https://localhost/portal/basic/",
interceptorUrlRegex: "https?://localhost.*" // add authorization to all URLs that match the given regex
},
...
Adjust the settings as required.
Finally, add the login tool to the tools.children
section in the config.json
:
"login": {
"name": "translate#additional:modules.tools.login.title",
"icon": "bi-door-open"
}
Make these changes in your standard masterportal deployment. When you deploy these and open your masterportal, the Login function should be available in the tools menu.
When this works, proceed with the next step.
7.3.4.3.3. Configuration of the Backend
To run the backend, the easiest way is using a docker image based on the Dockerfile in this repository.
Before, you have to copy the config.json
, service.json
and rest-service.json
to input folder of this repository. After that, run docker build . -t portal-backend
in the main folder of this repository.
To run the backend some configuration parameters are needed, these must be set as Environment Variables.
These parameters are are available in total:
PORT=8101 # Standard Port for the Backend, do not change when using docker
LOG_LEVEL=DEBUG # Log level for the Backend
TEST_MODE=TRUE # If true, the backend provides the ability to login itself. The next two Variables have to be set for this to work.
KEYCLOAK_USERNAME=<username_to_be_used_for_testing>
KEYCLOAK_PASSWORD=<password_to_be_used_for_testing>
#Keycloak configurations
KEYCLOAK_HOST=https://idm.<domain> # IDM host base URL, can be diffrent from keycloak
KEYCLOAK_GRANT_TYPE=password # grant type, keep the same
KEYCLOAK_REALM=<idm_realm> # IDM Realm name
KEYCLOAK_CLIENT_ID=<client_id> # IDM Client ID
KEYCLOAK_CLIENT_SECRET=<client_secret> # IDM Client Secret, can be emtpy with public clients. For more complex scenarios, you can provide the client credentials here
KEYCLOAK_PUBLIC_KEY="<idm_key>" # Client from IDM, which is used to sign the token(s)
PUBLIC_ROLE=<roleName> # The role name, which is used to access the public dataspaces
COOKIE_TOKEN_NAME=token # The name of the cookie, which is used to store the token
#File path
INPUT_FILE_PATH=input # Path to the input files - keep unchanged
SERVICE_INTERNET_INPUT_FILE=services # Name of the input file, services -> services.json
REST_SERVICES_INTERNET_INPUT_FILE=rest-services # Name of the input file, rest-services -> rest-services.json
CONFIG_INPUT_FILE=config # Name of the input file, services -> services.json, config -> config.json
INPUT_FILES_EXTENTION=.json # Extension of the input files
OUTPUT_FILES_EXTENTION=.json # Extension of the input files
OUTPUT_FILE_PATH=output # Extension of the input files
If you run the backend locally, you can provide these variables using an .env file.
For the docker version, use the follwing command:
docker run -d --name portal-backend \
-p 8081:8101 \
-e PORT=8101 \
-e LOG_LEVEL=DEBUG \
-e TEST_MODE=TRUE \
-e KEYCLOAK_USERNAME=username_to_be_used_for_testing \
-e KEYCLOAK_PASSWORD=password_to_be_used_for_testing \
-e KEYCLOAK_HOST=https://idm.<domain> \
-e KEYCLOAK_GRANT_TYPE=password \
-e KEYCLOAK_REALM=idm_realm \
-e KEYCLOAK_CLIENT_ID=client_id \
-e KEYCLOAK_CLIENT_SECRET=client_secret \
-e KEYCLOAK_PUBLIC_KEY="idm_key" \
-e PUBLIC_ROLE=roleName \
-e COOKIE_TOKEN_NAME=token \
-e INPUT_FILE_PATH=input \
-e SERVICE_INTERNET_INPUT_FILE=services \
-e REST_SERVICES_INTERNET_INPUT_FILE=rest-services \
-e CONFIG_INPUT_FILE=config \
-e INPUT_FILES_EXTENTION=.json \
-e OUTPUT_FILES_EXTENTION=.json \
-e OUTPUT_FILE_PATH=output \
portal-backend
After that, the backend should be up and running. You can test this by calling http://localhost:8101/config.json.
If this all works, open the config.js
of your masterportal and change the following lines:
layerConf: "http://localhost:8101/services.json",
restConf: "http://localhost:8101/rest-services.json",
portalConf: "http://localhost:8101/config.json",
When you now start the portal, you can login and the backend will deliver the configuration files to the portal.