This is an example of integrating multiple Jmix applications (services) into a single starter UI (Hub).
The Hub main menu is composed of menus of the service applications, taking into account permissions of the logged-in user. When the user clicks on a menu item in Hub, it redirects to the corresponding screen in the service application.
The repository contains the following projects:
hub
is a central application which provides common menu collected from service applicationscustomers
andorders
are service applications connected to the Hubintegration
is an add-on providing common functionality for service applications available through the Hub
-
Create different host names for the appplications running on localhost. Add the following lines to your
hosts
file:127.0.0.1 host0 127.0.0.1 host1 127.0.0.1 host2
-
Run Keycloak on port 8180:
docker run -p 8180:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin --name=keycloak quay.io/keycloak/keycloak:18.0.2 start-dev
Admin UI will be available at
http://localhost:8180/admin
. Log in as admin/admin. -
Configure Keycloak
-
Create
sample-hub
realm. -
Create clients:
-
hub
withhttp://host0:8080/
root URL -
customers
withhttp://host1:8081/
root URL -
orders
withhttp://host2:8082/
root URLSet Access Type to
confidential
for all clients.
-
-
For all clients, create a mapper on Mappers tab:
- Type:
User Realm Role
- Token Claim Name:
roles
- Type:
-
Create
system-full-access
,ui-minimal
,worker
,manager
roles. -
Create users:
-
admin
withsystem-full-access
role -
alice
withui-minimal
andmanager
roles -
bob
withui-minimal
andworker
rolesWhen setting passwords for users, turn off Temporary flag. Roles are assigned on the Role Mappings tab.
-
-
-
Open terminal in
integration
directory and run./gradlew publishToMavenLocal
to install the add-on to the local Maven repo. In case you got this errorjava.lang.IllegalArgumentException: Unsupported class file major version 65
check the Java version used by your terminal (java -version
). It should be 17. -
Open
hub
project in IDE and setspring.security.oauth2.client.registration.keycloak.client-secret
property to the value obtained from the Credentials tab of thehub
application in Keycloak. Do the same forcustomers
andorders
projects. -
Run all projects.
Open http://host0:8080
in web browser. You will be redirected to Keycloak login form.
Log in as alice
. You will land in the Hub application, which will show menus of Customers and Orders applications with items available to user alice
in this apps.
Click on Customers App -> Application -> Customers. The Hub will redirect you to Customers app at http://host1:8081
and show the Customers browse screen of this app.
You can go back to Hub either using the browser back button or clicking Go to Hub in the main menu.
The integration
add-on provides a REST endpoint /integration/menu
for getting menu structure of the service application, see MenuController. The controller transforms the menu configuration to the collection of DTOs, checking current user permissions for each item. The endpoint is authenticated, see AuthorizedUrlsProvider
bean in IntConfiguration.
The customers
and orders
projects use the integration
add-on, and therefore automatically expose the /integration/menu
endpoint. They also create a menu item to go to the Hub application, see onAfterShow()
method of MainScreen.
Each service application has its own set of roles named manager
and worker
, for managing permissions to entities and UI of the application. See ManagerRole and the like. The roles are assigned to a user in Keycloak and used when the user is authenticated in an application.
Service applications are registered in Hub using its integration.appNames
and integration.appUrls
properties.
The Hub application in onAfterShow()
method of MainScreen builds main menu by retrieving it from all registered service applications. MenuRetriever bean requests the service application's /integration/menu
endpoint, providing the authentication token which was stored in a session attribute by AuthenticationSuccessListener when the user logged in to the Hub application.
The integration
add-on also provides the /integration/logout
REST endpoint for logging out from a service application by a signal from the Hub, see LogoutController.
OAuth2LoginSecurityConfiguration configures session management for OIDC-based authentication. It will be included in the next version of the OIDC add-on and will not be needed in this project.