From aea132625371f26cbad9a12a6233afc00d32ae66 Mon Sep 17 00:00:00 2001 From: deiflaender Date: Fri, 24 Mar 2023 16:16:41 +0100 Subject: [PATCH 1/2] RED-4515: Get tenant from bearer token --- ...stenceServiceExternalApiConfiguration.java | 5 +-- .../HeaderBasedKeycloakRealmResolver.java | 31 ++++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/PersistenceServiceExternalApiConfiguration.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/PersistenceServiceExternalApiConfiguration.java index a8bda5e51..f95d1fd57 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/PersistenceServiceExternalApiConfiguration.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/PersistenceServiceExternalApiConfiguration.java @@ -7,6 +7,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import com.fasterxml.jackson.databind.ObjectMapper; import com.iqser.red.persistence.service.v1.external.api.impl.multitenacy.HeaderBasedKeycloakRealmResolver; @Configuration @@ -14,8 +15,8 @@ import com.iqser.red.persistence.service.v1.external.api.impl.multitenacy.Header public class PersistenceServiceExternalApiConfiguration { @Bean - public KeycloakConfigResolver keycloakConfigResolver() { - return new HeaderBasedKeycloakRealmResolver(); + public KeycloakConfigResolver keycloakConfigResolver(ObjectMapper objectMapper) { + return new HeaderBasedKeycloakRealmResolver(objectMapper); } @Autowired diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java index 576088edd..5c0ba3f91 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java @@ -2,6 +2,7 @@ package com.iqser.red.persistence.service.v1.external.api.impl.multitenacy; import static com.iqser.red.service.persistence.management.v1.processor.multitenancy.TenantInterceptor.TENANT_HEADER_NAME; +import java.util.Base64; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -13,12 +14,17 @@ import org.keycloak.adapters.OIDCHttpFacade; import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.representations.adapters.config.AdapterConfig; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter; +import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @Slf4j +@RequiredArgsConstructor public class HeaderBasedKeycloakRealmResolver implements KeycloakConfigResolver { private final Map cache = new ConcurrentHashMap<>(); @@ -27,6 +33,7 @@ public class HeaderBasedKeycloakRealmResolver implements KeycloakConfigResolver private static AdapterConfig adapterConfig; private KeycloakDeployment defaultDeployment; + private final ObjectMapper objectMapper; @Override @@ -34,6 +41,11 @@ public class HeaderBasedKeycloakRealmResolver implements KeycloakConfigResolver String tenant = getHeader(request, TENANT_HEADER_NAME); + if (tenant == null) { + // TODO always send as header and remove this. + tenant = getTenantFromBearerToken(request); + } + if (tenant == null) { if (defaultDeployment == null) { defaultDeployment = KeycloakDeploymentBuilder.build(adapterConfig); @@ -45,12 +57,29 @@ public class HeaderBasedKeycloakRealmResolver implements KeycloakConfigResolver } + @SneakyThrows + private String getTenantFromBearerToken(HttpFacade.Request request) { + + String authHeader = request.getHeader("Authorization"); + if (authHeader == null) { + return null; + } + String[] chunks = authHeader.split(" ")[1].split("\\."); + Base64.Decoder decoder = Base64.getUrlDecoder(); + + String payload = new String(decoder.decode(chunks[1])); + JsonNode actualObj = objectMapper.readTree(payload); + String issuer = actualObj.get("iss").asText(); + return issuer.substring(issuer.lastIndexOf('/') + 1); + } + + private KeycloakDeployment createKeyCloakDeployment(String tenant) { var config = MagicConverter.convert(adapterConfig, AdapterConfig.class); config.setRealm(tenant); config.setResource(tenant); - + return KeycloakDeploymentBuilder.build(config); } From a20ed3a6af19b51345d43516095934c576110d6f Mon Sep 17 00:00:00 2001 From: deiflaender Date: Fri, 24 Mar 2023 17:56:29 +0100 Subject: [PATCH 2/2] RED-4515: Fixed wrong setting of resource --- .../api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java | 3 +-- .../src/test/resources/application.yml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java index 5c0ba3f91..a7df36a1f 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/multitenacy/HeaderBasedKeycloakRealmResolver.java @@ -78,8 +78,7 @@ public class HeaderBasedKeycloakRealmResolver implements KeycloakConfigResolver var config = MagicConverter.convert(adapterConfig, AdapterConfig.class); config.setRealm(tenant); - config.setResource(tenant); - + return KeycloakDeploymentBuilder.build(config); } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml index 564764660..353ef50fb 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml @@ -119,7 +119,7 @@ keycloak: enabled: true sslRequired: none realm: master - resource: master + resource: redaction disableTrustManager: true useResourceRoleMappings: true