keycloak(feat): add recipes for client management
This commit is contained in:
88
keycloak/scripts/add-client-roles-to-profile-scope.ts
Normal file
88
keycloak/scripts/add-client-roles-to-profile-scope.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
import KcAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
async function main() {
|
||||
const kcAdminClient = new KcAdminClient({
|
||||
baseUrl: `https://${process.env.KEYCLOAK_HOST}`,
|
||||
realmName: "master",
|
||||
});
|
||||
|
||||
await kcAdminClient.auth({
|
||||
username: process.env.KEYCLOAK_ADMIN_USER!,
|
||||
password: process.env.KEYCLOAK_ADMIN_PASSWORD!,
|
||||
grantType: "password",
|
||||
clientId: "admin-cli",
|
||||
});
|
||||
|
||||
const realm = process.env.KEYCLOAK_REALM!;
|
||||
const clientId = process.env.KEYCLOAK_CLIENT_ID!;
|
||||
const claimName = process.env.CLAIM_NAME || "client_roles";
|
||||
|
||||
invariant(realm, "KEYCLOAK_REALM is required");
|
||||
invariant(clientId, "KEYCLOAK_CLIENT_ID is required");
|
||||
|
||||
kcAdminClient.setConfig({ realmName: realm });
|
||||
|
||||
try {
|
||||
// Find the profile client scope
|
||||
const clientScopes = await kcAdminClient.clientScopes.find({ realm });
|
||||
const profileScope = clientScopes.find(scope => scope.name === 'profile');
|
||||
|
||||
if (!profileScope) {
|
||||
throw new Error("Profile client scope not found");
|
||||
}
|
||||
|
||||
console.log(`Found profile scope: ${profileScope.id}`);
|
||||
|
||||
// Check existing mappers in profile scope
|
||||
const existingMappers = await kcAdminClient.clientScopes.listProtocolMappers({
|
||||
realm,
|
||||
id: profileScope.id!,
|
||||
});
|
||||
|
||||
console.log("Existing mappers in profile scope:");
|
||||
existingMappers.forEach(mapper => {
|
||||
console.log(`- ${mapper.name} (${mapper.protocolMapper})`);
|
||||
});
|
||||
|
||||
// Check if our client roles mapper already exists in profile scope
|
||||
const clientRolesMapper = existingMappers.find(m =>
|
||||
m.config?.['usermodel.clientRoleMapping.clientId'] === clientId
|
||||
);
|
||||
|
||||
if (clientRolesMapper) {
|
||||
console.log(`Client roles mapper already exists in profile scope: ${clientRolesMapper.name}`);
|
||||
} else {
|
||||
console.log(`Adding ${clientId} client roles mapper to profile scope...`);
|
||||
|
||||
// Add client roles mapper to profile scope
|
||||
await kcAdminClient.clientScopes.addProtocolMapper(
|
||||
{ realm, id: profileScope.id! },
|
||||
{
|
||||
name: `${clientId} Client Roles`,
|
||||
protocol: "openid-connect",
|
||||
protocolMapper: "oidc-usermodel-client-role-mapper",
|
||||
config: {
|
||||
"userinfo.token.claim": "true",
|
||||
"id.token.claim": "true",
|
||||
"access.token.claim": "true",
|
||||
"claim.name": claimName,
|
||||
"jsonType.label": "String",
|
||||
"multivalued": "true",
|
||||
"usermodel.clientRoleMapping.clientId": clientId,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
console.log(`✓ Added ${clientId} client roles mapper to profile scope`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Error: ${error}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
Reference in New Issue
Block a user