diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 6677f6811..dcd80b787 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -112,7 +112,7 @@ jobs: gke-project: ${{ secrets.GKE_PROJECT }} cloudflare-api-token: ${{ secrets.CF_API_TOKEN }} cloudflare-zone-id: ${{ secrets.CF_ZONE_ID }} - keycloak-admin-password: ${{ secrets.KEYCLOAK_ADMIN_PASSWORD }} + keycloak-admin-password: ${{ secrets.KC_BOOTSTRAP_ADMIN_PASSWORD }} check: name: Check diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d560d20c5..68b9240d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,7 +126,7 @@ jobs: CADDY_MERCURE_JWT_SECRET: 33b04d361e437e0d7d715600fc24fdefba317154 POSTGRES_PASSWORD: aae5bf316ef5fe87ad806c6a9240fff68bcfdaf7 KEYCLOAK_POSTGRES_PASSWORD: 26d7f630f1524eb210bbf496443f2038a9316e9e - KEYCLOAK_ADMIN_PASSWORD: 2f31e2fad93941b818449fd8d57fd019b6ce7fa5 + KC_BOOTSTRAP_ADMIN_PASSWORD: 2f31e2fad93941b818449fd8d57fd019b6ce7fa5 # https://nextjs.org/docs/app/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser NEXT_PUBLIC_OIDC_SERVER_URL: https://localhost/oidc/realms/demo # https://docs.docker.com/compose/environment-variables/envvars/#compose_file diff --git a/api/src/Security/Http/Protection/ResourceResourceHandler.php b/api/src/Security/Http/Protection/ResourceResourceHandler.php index aa1a69a46..888d41ca6 100644 --- a/api/src/Security/Http/Protection/ResourceResourceHandler.php +++ b/api/src/Security/Http/Protection/ResourceResourceHandler.php @@ -38,7 +38,7 @@ public function create(object $resource, UserInterface $owner, array $context = ); // create resource_set on OIDC server - $this->securityAuthorizationClient->request('POST', $this->getResourceRegistrationEndpoint(), [ + $response = $this->securityAuthorizationClient->request('POST', 'authz/protection/resource_set', [ 'auth_bearer' => $this->getPAT(), 'json' => [ 'name' => \sprintf('%s_%s', $shortName, $resource->getId()->__toString()), @@ -48,6 +48,9 @@ public function create(object $resource, UserInterface $owner, array $context = 'owner' => $owner->getUserIdentifier(), ], ]); + if (200 !== $response->getStatusCode()) { + dump($response->toArray(false)); + } } public function delete(object $resource, UserInterface $owner, array $context = []): void @@ -66,7 +69,7 @@ public function delete(object $resource, UserInterface $owner, array $context = // retrieve corresponding resource_set from OIDC server $response = $this->securityAuthorizationClient->request( 'GET', - $this->getResourceRegistrationEndpoint(), + 'authz/protection/resource_set', [ 'auth_bearer' => $this->getPAT(), 'query' => [ @@ -85,7 +88,7 @@ public function delete(object $resource, UserInterface $owner, array $context = // delete corresponding resource_set on OIDC server $this->securityAuthorizationClient->request( 'DELETE', - \sprintf('%s/%s', $this->getResourceRegistrationEndpoint(), $resourceSet['_id']), + \sprintf('%s/%s', 'authz/protection/resource_set', $resourceSet['_id']), [ 'auth_bearer' => $this->getPAT(), ] @@ -97,7 +100,7 @@ public function delete(object $resource, UserInterface $owner, array $context = */ private function getPAT(): string { - $response = $this->securityAuthorizationClient->request('POST', $this->getTokenEndpoint(), [ + $response = $this->securityAuthorizationClient->request('POST', 'protocol/openid-connect/token', [ 'body' => [ 'grant_type' => 'client_credentials', 'client_id' => $this->oidcClientId, @@ -108,20 +111,4 @@ private function getPAT(): string return $content['access_token']; } - - private function getTokenEndpoint(): string - { - $response = $this->securityAuthorizationClient->request('GET', '.well-known/openid-configuration'); - $content = $response->toArray(); - - return $content['token_endpoint']; - } - - private function getResourceRegistrationEndpoint(): string - { - $response = $this->securityAuthorizationClient->request('GET', '.well-known/uma2-configuration'); - $content = $response->toArray(); - - return $content['resource_registration_endpoint']; - } } diff --git a/compose.e2e.yaml b/compose.e2e.yaml index 80fb79663..107e05b06 100644 --- a/compose.e2e.yaml +++ b/compose.e2e.yaml @@ -3,13 +3,11 @@ services: environment: KEYCLOAK_ENABLE_HTTPS: "true" KEYCLOAK_HTTPS_USE_PEM: "true" + KC_LOG_LEVEL: "debug" KEYCLOAK_HTTPS_CERTIFICATE_FILE: /opt/bitnami/keycloak/certs/tls.crt KEYCLOAK_HTTPS_CERTIFICATE_KEY_FILE: /opt/bitnami/keycloak/certs/tls.key + KEYCLOAK_EXTRA_ARGS: "--features=\"hostname:v2,scripts,persistent-user-sessions:v1\" --hostname-backchannel-dynamic=true --import-realm" volumes: - ./helm/api-platform/keycloak/certs/tls.crt:/opt/bitnami/keycloak/certs/tls.crt:ro - ./helm/api-platform/keycloak/certs/tls.pem:/opt/bitnami/keycloak/certs/tls.key:ro - - keycloak-config-cli: - extends: - file: compose.override.yaml - service: keycloak-config-cli + - ./helm/api-platform/keycloak/config:/opt/bitnami/keycloak/data/import diff --git a/compose.override.yaml b/compose.override.yaml index b073517e7..060470b9d 100644 --- a/compose.override.yaml +++ b/compose.override.yaml @@ -50,17 +50,8 @@ services: build: context: ./helm/api-platform/keycloak/ target: keycloak - volumes: - - ./helm/api-platform/keycloak/themes/api-platform-demo:/opt/bitnami/keycloak/themes/api-platform-demo - - keycloak-config-cli: - image: bitnami/keycloak-config-cli:5-debian-12 environment: - KEYCLOAK_URL: http://keycloak:8080/oidc/ - KEYCLOAK_USER: ${KEYCLOAK_ADMIN_USER:-admin} - KEYCLOAK_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-!ChangeMe!} - KEYCLOAK_AVAILABILITYCHECK_ENABLED: "true" - KEYCLOAK_AVAILABILITYCHECK_TIMEOUT: 120s - IMPORT_FILES_LOCATIONS: "/config/*" + KEYCLOAK_EXTRA_ARGS: "--features=\"hostname:v2,scripts,persistent-user-sessions:v1\" --hostname-backchannel-dynamic=true --import-realm" volumes: - - ./helm/api-platform/keycloak/config:/config + - ./helm/api-platform/keycloak/themes/api-platform-demo:/opt/bitnami/keycloak/themes/api-platform-demo + - ./helm/api-platform/keycloak/config:/opt/bitnami/keycloak/data/import diff --git a/compose.prod.yaml b/compose.prod.yaml index bfc0c38ee..a62c0304a 100644 --- a/compose.prod.yaml +++ b/compose.prod.yaml @@ -38,4 +38,4 @@ services: target: keycloak environment: KEYCLOAK_PRODUCTION: "true" - KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} + KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_BOOTSTRAP_ADMIN_PASSWORD} diff --git a/compose.yaml b/compose.yaml index 87a8750cc..e72800132 100644 --- a/compose.yaml +++ b/compose.yaml @@ -79,15 +79,13 @@ services: KEYCLOAK_DATABASE_NAME: ${KEYCLOAK_POSTGRES_DB:-keycloak} KEYCLOAK_DATABASE_USER: ${KEYCLOAK_POSTGRES_USER:-keycloak} KEYCLOAK_DATABASE_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD:-!ChangeMe!} - KEYCLOAK_ADMIN_USER: ${KEYCLOAK_ADMIN_USER:-admin} - KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-!ChangeMe!} + KC_BOOTSTRAP_ADMIN_USERNAME: ${KC_BOOTSTRAP_ADMIN_USERNAME:-admin} + KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_BOOTSTRAP_ADMIN_PASSWORD:-!ChangeMe!} # Must finish with a trailing slash (https://github.com/bitnami/charts/issues/10885#issuecomment-1414279144) KEYCLOAK_HTTP_RELATIVE_PATH: /oidc/ - # https://www.keycloak.org/server/hostname - KC_HOSTNAME_URL: https://${SERVER_NAME:-localhost}/oidc/ - KC_HOSTNAME_ADMIN_URL: https://${SERVER_NAME:-localhost}/oidc/ - # https://www.keycloak.org/server/features - KC_FEATURES: "scripts" + KEYCLOAK_HOSTNAME: https://${SERVER_NAME:-localhost}/oidc/ + KEYCLOAK_HOSTNAME_ADMIN: https://${SERVER_NAME:-localhost}/oidc/ + KEYCLOAK_EXTRA_ARGS: "--features=\"hostname:v2,scripts,persistent-user-sessions:v1\" --hostname-backchannel-dynamic=true" depends_on: - keycloak-database ports: diff --git a/helm/api-platform/keycloak/Dockerfile b/helm/api-platform/keycloak/Dockerfile index d5e2b08d5..bcdb365b5 100644 --- a/helm/api-platform/keycloak/Dockerfile +++ b/helm/api-platform/keycloak/Dockerfile @@ -4,7 +4,7 @@ # Versions -FROM bitnami/keycloak:24-debian-12 AS keycloak_upstream +FROM bitnami/keycloak:26-debian-12 AS keycloak_upstream # The different stages of this Dockerfile are meant to be built into separate images diff --git a/helm/api-platform/values.yaml b/helm/api-platform/values.yaml index 229d8d8bc..cf104e9d8 100644 --- a/helm/api-platform/values.yaml +++ b/helm/api-platform/values.yaml @@ -108,14 +108,16 @@ keycloak: service: type: ClusterIP extraEnvVars: - # Must set KC_HOSTNAME_URL to force https + relative path - - name: KC_HOSTNAME_URL + # Must set KEYCLOAK_HOSTNAME to force https + relative path + - name: KEYCLOAK_HOSTNAME value: "https://chart-example.local/oidc/" - # Must set KC_HOSTNAME_ADMIN because of relative path - - name: KC_HOSTNAME_ADMIN_URL + # Must set KEYCLOAK_HOSTNAME_ADMIN because of relative path + - name: KEYCLOAK_HOSTNAME_ADMIN value: "https://chart-example.local/oidc/" - name: KEYCLOAK_PRODUCTION value: "true" + - name: KEYCLOAK_EXTRA_ARGS + value: "--features=\"hostname:v2,scripts,persistent-user-sessions:v1\" --hostname-backchannel-dynamic=true" # must finish with a trailing slash (https://github.com/bitnami/charts/issues/10885#issuecomment-1414279144) httpRelativePath: /oidc/ proxy: edge @@ -137,7 +139,7 @@ keycloak: - -jar - /opt/bitnami/keycloak-config-cli/keycloak-config-cli.jar image: - tag: 5-debian-12 + tag: 6-debian-12 postgresql: enabled: true nameOverride: postgresql-keycloak