Pull request #639: RED-4515: Get tenant from bearer token

Merge in RED/persistence-service from RED-4515 to master

* commit 'a20ed3a6af19b51345d43516095934c576110d6f':
  RED-4515: Fixed wrong setting of resource
  RED-4515: Get tenant from bearer token
This commit is contained in:
Dominique Eiflaender 2023-03-24 18:16:29 +01:00
commit e71adaaa37
3 changed files with 33 additions and 4 deletions

View File

@ -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

View File

@ -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<String, KeycloakDeployment> 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,11 +57,27 @@ 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);
}

View File

@ -119,7 +119,7 @@ keycloak:
enabled: true
sslRequired: none
realm: master
resource: master
resource: redaction
disableTrustManager: true
useResourceRoleMappings: true