From 55861fbe4c45615daf67de727dde543105bc9205 Mon Sep 17 00:00:00 2001 From: Mauro Mugnaini Date: Thu, 20 May 2021 18:28:41 +0200 Subject: [PATCH] Now orchestrators calls are UMA authenticated with keycloak-client credentials and audience --- .../OrchestratorEventPublisherProvider.java | 18 ++-- ...estratorEventPublisherProviderFactory.java | 97 ++++++++++++++----- 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProvider.java b/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProvider.java index cb2fea9..2029996 100644 --- a/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProvider.java +++ b/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProvider.java @@ -47,10 +47,6 @@ public class OrchestratorEventPublisherProvider extends AbstractEventPublisher @Override public void onEvent(Event event) { -// if (event.getError() != null) { -// logger.debug("Skipping error event publish"); -// return; -// } if (!INTERESTING_EVENTS.contains(event.getType())) { logger.debug("Skipping publish of not interesting event"); return; @@ -71,11 +67,17 @@ public class OrchestratorEventPublisherProvider extends AbstractEventPublisher @Override protected EventSender createEventSender() { - logger.infof("Creating the HTTP event sender with endpoint: %s", - OrchestratorEventPublisherProviderFactory.endpoint); + logger.infof( + "Creating the HTTP event sender with endpoint: %s, clientId: %s, KC token endpoint: %s, UMA adience: %s", + OrchestratorEventPublisherProviderFactory.ORCHESTRATOR_ENDPOINT, + OrchestratorEventPublisherProviderFactory.KEYCLOAK_ENDPOINT, + OrchestratorEventPublisherProviderFactory.KEYCLOAK_CLIENT_ID); - return new HTTPWithUMAAuthEventSender(OrchestratorEventPublisherProviderFactory.endpoint, null, null, null, - null); + return new HTTPWithUMAAuthEventSender(OrchestratorEventPublisherProviderFactory.ORCHESTRATOR_ENDPOINT, + OrchestratorEventPublisherProviderFactory.KEYCLOAK_CLIENT_ID, + OrchestratorEventPublisherProviderFactory.KEYCLOAK_CLIENT_SECRET, + OrchestratorEventPublisherProviderFactory.KEYCLOAK_ENDPOINT, + OrchestratorEventPublisherProviderFactory.KEYCLOAK_CLIENT_ID); } } diff --git a/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProviderFactory.java b/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProviderFactory.java index e1c96df..f650e57 100644 --- a/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProviderFactory.java +++ b/event-listener-provider/src/main/java/org/gcube/keycloak/event/OrchestratorEventPublisherProviderFactory.java @@ -17,11 +17,19 @@ import org.keycloak.models.RealmModel; */ public class OrchestratorEventPublisherProviderFactory implements EventListenerProviderFactory { - public static final String ORCHESTRATOR_CLIENT_ID = "orchestrator"; - private static final Logger logger = Logger.getLogger(OrchestratorEventPublisherProviderFactory.class); - public static URL endpoint; + public static final String MASTER_REALM_NAME = "master"; + public static final String ORCHESTRATOR_CLIENT_ID = "orchestrator"; + public static final String KEYCLOAK_CLIENT_ID = "keycloak-client"; + + private static final int CHECK_DELAY = 60 * 1000; // One minute + + public static URL ORCHESTRATOR_ENDPOINT; + public static URL KEYCLOAK_ENDPOINT; + public static String KEYCLOAK_CLIENT_SECRET; + + protected Long lastEndpointCheck = new Long(0); protected OrchestratorEventPublisherProvider oepp; public OrchestratorEventPublisherProviderFactory() { @@ -34,35 +42,74 @@ public class OrchestratorEventPublisherProviderFactory implements EventListenerP @Override public synchronized OrchestratorEventPublisherProvider create(KeycloakSession keycloakSession) { - logger.debug("Getting actual realm from session's context"); - RealmModel realm = keycloakSession.getContext().getRealm(); + Long now = System.currentTimeMillis(); + Long elapsed = now - lastEndpointCheck; + if (oepp == null || elapsed > CHECK_DELAY) { + lastEndpointCheck = now; + ClientModel orchestratorClient = getClientInActualOrMasterRealm(keycloakSession, ORCHESTRATOR_CLIENT_ID); + ClientModel keycloakClient = getClientInActualOrMasterRealm(keycloakSession, KEYCLOAK_CLIENT_ID); + logger.debug("Getting configured orchestrator endpoint address from client's base URL"); + String orchestratorAddress = orchestratorClient.getBaseUrl(); + logger.debug("Getting configured keycloak endpoint address from client's base URL"); + String keycloakAddress = keycloakClient.getBaseUrl(); + logger.debug("Getting configured keycloak client client-secret from client"); + String keycloakClientSecret = keycloakClient.getSecret(); + URL newOrchestratorEndpoint; + URL newKeycloakEndpoint; + try { + newOrchestratorEndpoint = new URL(orchestratorAddress); + } catch (MalformedURLException e) { + logger.errorf("Can't create new orchestrator endpoint address: %s", + orchestratorAddress, e); + oepp = null; + return null; + } + try { + newKeycloakEndpoint = new URL(keycloakAddress); + } catch (MalformedURLException e) { + logger.errorf("Can't create new keycloak token address: %s", keycloakAddress, e); + oepp = null; + return null; + } + if (oepp == null || !newOrchestratorEndpoint.equals(ORCHESTRATOR_ENDPOINT) + || !newKeycloakEndpoint.equals(KEYCLOAK_ENDPOINT) + || !keycloakClientSecret.equals(KEYCLOAK_CLIENT_SECRET)) { - logger.debugf("Getting configured endpoint address for client '%s' in realm '%s'", ORCHESTRATOR_CLIENT_ID, - realm.getName()); - - ClientModel client = realm.getClientByClientId(ORCHESTRATOR_CLIENT_ID); - if (client == null) { - logger.warnf("Cannot find %s client in realm: %s", ORCHESTRATOR_CLIENT_ID, realm.getName()); - return null; - } - - String address = client.getBaseUrl(); - try { - URL newEndpoint = new URL(address); - if (oepp == null || !newEndpoint.equals(endpoint)) { - logger.infof("Creating new orchestrator event publisher provider for endpoint: %s", address); - OrchestratorEventPublisherProviderFactory.endpoint = newEndpoint; - // Endpoint address will be read from 'address' static field in this class + logger.infof("Creating new orchestrator event publisher provider for endpoint: %s", + orchestratorAddress); + // Address and other fileds will be then read from static fields in this class by + // the createEventSender() called by the superclass' constructor, overridden in the impl. + ORCHESTRATOR_ENDPOINT = newOrchestratorEndpoint; + KEYCLOAK_ENDPOINT = newKeycloakEndpoint; + KEYCLOAK_CLIENT_SECRET = keycloakClientSecret; oepp = new OrchestratorEventPublisherProvider(); } - } catch (MalformedURLException e) { - logger.error("Can't create new orchestrator event publisher provider with endpoint address: " + address, - e); - oepp = null; + + } else { + logger.debugf("Next check is in %d millis", CHECK_DELAY - elapsed); } return oepp; } + protected ClientModel getClientInActualOrMasterRealm(KeycloakSession keycloakSession, String clientId) { + logger.debug("Getting actual realm from session's context"); + RealmModel realm = keycloakSession.getContext().getRealm(); + logger.debugf("Trying getting '%s' client in current realm '%s'", clientId, realm.getName()); + ClientModel client = realm.getClientByClientId(clientId); + if (client == null) { + logger.debugf("Not found. Now trying getting '%s' in '%s' realm", clientId, MASTER_REALM_NAME); + realm = keycloakSession.realms().getRealmByName(MASTER_REALM_NAME); + client = realm.getClientByClientId(clientId); + if (client == null) { + logger.warnf("Cannot find '%s' client not even in '%s' realm", clientId, realm.getName(), + MASTER_REALM_NAME); + + return null; + } + } + return client; + } + @Override public String getId() { return "orchestrator-event-publisher";