From d1eef065a4d84f08efb8004df25bbea60b042434 Mon Sep 17 00:00:00 2001 From: Masaki Yatsu Date: Thu, 18 Sep 2025 23:21:31 +0900 Subject: [PATCH] feat(keycloak): support direct access grant --- keycloak/justfile | 23 +++++++++++++---------- keycloak/scripts/create-client.ts | 6 ++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/keycloak/justfile b/keycloak/justfile index 752f330..234aeb1 100644 --- a/keycloak/justfile +++ b/keycloak/justfile @@ -202,7 +202,7 @@ client-exists realm client_id: dotenvx run -q -f ../.env.local -- tsx ./scripts/client-exists.ts # Create Keycloak client -create-client realm client_id redirect_url client_secret='' session_idle='' session_max='': +create-client realm client_id redirect_url client_secret='' session_idle='' session_max='' direct_access_grants='false': #!/bin/bash set -euo pipefail export KEYCLOAK_ADMIN_USER=$(just admin-username) @@ -213,8 +213,20 @@ create-client realm client_id redirect_url client_secret='' session_idle='' sess export KEYCLOAK_REDIRECT_URL={{ redirect_url }} export KEYCLOAK_CLIENT_SESSION_IDLE={{ session_idle }} export KEYCLOAK_CLIENT_SESSION_MAX={{ session_max }} + export KEYCLOAK_CLIENT_DIRECT_ACCESS_GRANTS={{ direct_access_grants }} dotenvx run -q -f ../.env.local -- tsx ./scripts/create-client.ts +# Add audience mapper to existing client +add-audience-mapper realm client_id audience: + #!/bin/bash + set -euo pipefail + export KEYCLOAK_ADMIN_USER=$(just admin-username) + export KEYCLOAK_ADMIN_PASSWORD=$(just admin-password) + export KEYCLOAK_REALM={{ realm }} + export KEYCLOAK_CLIENT_ID={{ client_id }} + export KEYCLOAK_AUDIENCE={{ audience }} + dotenvx run -q -f ../.env.local -- tsx ./scripts/add-audience-mapper.ts + # Delete Keycloak client delete-client realm client_id: #!/bin/bash @@ -225,15 +237,6 @@ delete-client realm client_id: export KEYCLOAK_CLIENT_ID={{ client_id }} dotenvx run -q -f ../.env.local -- tsx ./scripts/delete-client.ts -# Add Keycloak client audience mapper -add-audience-mapper client_id: - #!/bin/bash - set -euo pipefail - export KEYCLOAK_ADMIN_USER=$(just admin-username) - export KEYCLOAK_ADMIN_PASSWORD=$(just admin-password) - export KEYCLOAK_REALM=${KEYCLOAK_REALM} - export KEYCLOAK_CLIENT_ID={{ client_id }} - dotenvx run -q -f ../.env.local -- tsx ./scripts/add-audience-mapper.ts # Add attribute mapper for Keycloak client add-attribute-mapper client_id attribute_name display_name='' claim_name='' options='' default_value='' mapper_name='' view_perms='admin,user' edit_perms='admin': diff --git a/keycloak/scripts/create-client.ts b/keycloak/scripts/create-client.ts index 40dffa7..de6b3f3 100644 --- a/keycloak/scripts/create-client.ts +++ b/keycloak/scripts/create-client.ts @@ -26,6 +26,7 @@ const main = async () => { const sessionIdle = process.env.KEYCLOAK_CLIENT_SESSION_IDLE; const sessionMax = process.env.KEYCLOAK_CLIENT_SESSION_MAX; + const directAccessGrants = process.env.KEYCLOAK_CLIENT_DIRECT_ACCESS_GRANTS; const kcAdminClient = new KcAdminClient({ baseUrl: `https://${keycloakHost}`, @@ -55,6 +56,7 @@ const main = async () => { enabled: true, redirectUris: redirectUris, publicClient: clientSecret && clientSecret !== '' ? false : true, + directAccessGrantsEnabled: directAccessGrants === 'true', }; // Add session timeout settings if provided @@ -70,6 +72,10 @@ const main = async () => { console.log(`Setting Client Session Max Lifespan: ${sessionMax}`); } + if (directAccessGrants === 'true') { + console.log('Enabling Direct Access Grants (Resource Owner Password Credentials)'); + } + const createdClient = await kcAdminClient.clients.create(clientConfig); console.log(`Client created successfully with ID: ${createdClient.id}`); } catch (error) {