keycloak-api-manager 5.0.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/docs/api/attack-detection.md +42 -0
- package/docs/api/authentication-management.md +160 -0
- package/docs/api/client-policies.md +66 -0
- package/docs/api/client-scopes.md +194 -0
- package/docs/api/clients.md +450 -0
- package/docs/api/components.md +57 -0
- package/docs/api/configuration.md +447 -0
- package/docs/api/groups.md +129 -0
- package/docs/api/identity-providers.md +98 -0
- package/docs/api/organizations.md +615 -0
- package/docs/api/realms.md +277 -0
- package/docs/api/roles.md +102 -0
- package/docs/api/server-info.md +38 -0
- package/docs/api/user-profile.md +63 -0
- package/docs/api/users.md +1563 -0
- package/docs/api-reference.md +163 -0
- package/package.json +1 -1
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# Configuration & Authentication
|
|
2
|
+
|
|
3
|
+
Core API methods for initializing and managing the Keycloak Admin Client connection.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [configure()](#configure)
|
|
8
|
+
- [setConfig()](#setconfig)
|
|
9
|
+
- [getToken()](#gettoken)
|
|
10
|
+
- [auth()](#auth)
|
|
11
|
+
- [stop()](#stop)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## configure()
|
|
16
|
+
|
|
17
|
+
Initialize and authenticate the Keycloak Admin Client. Must be called before using any handler methods.
|
|
18
|
+
|
|
19
|
+
**Syntax:**
|
|
20
|
+
```javascript
|
|
21
|
+
await KeycloakManager.configure(credentials)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Parameters
|
|
25
|
+
|
|
26
|
+
#### credentials (Object) ⚠️ Required
|
|
27
|
+
|
|
28
|
+
Authentication configuration object.
|
|
29
|
+
|
|
30
|
+
| Property | Type | Required | Description |
|
|
31
|
+
|----------|------|----------|-------------|
|
|
32
|
+
| `baseUrl` | string | ⚠️ Yes | Keycloak server base URL (e.g., `https://keycloak.example.com:8443`) |
|
|
33
|
+
| `realmName` | string | ⚠️ Yes | Target realm name for authentication (usually `master`) |
|
|
34
|
+
| `grantType` | string | ⚠️ Yes | OAuth2 grant type: `'password'` or `'client_credentials'` |
|
|
35
|
+
| `clientId` | string | ⚠️ Yes | Client ID (e.g., `admin-cli` for password grant) |
|
|
36
|
+
| `username` | string | 📋 Conditional | Required for `password` grant type |
|
|
37
|
+
| `password` | string | 📋 Conditional | Required for `password` grant type |
|
|
38
|
+
| `clientSecret` | string | 📋 Conditional | Required for `client_credentials` grant type |
|
|
39
|
+
| `tokenLifeSpan` | number | 📋 Optional | Token refresh interval in seconds (default: 60) |
|
|
40
|
+
| `scope` | string | 📋 Optional | OAuth2 scope (e.g., `'offline_access'` for refresh tokens) |
|
|
41
|
+
|
|
42
|
+
### Returns
|
|
43
|
+
|
|
44
|
+
**Promise\<void\>** - Resolves when authentication succeeds
|
|
45
|
+
|
|
46
|
+
### Examples
|
|
47
|
+
|
|
48
|
+
#### Password Grant (Admin User)
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const KeycloakManager = require('keycloak-api-manager');
|
|
52
|
+
|
|
53
|
+
await KeycloakManager.configure({
|
|
54
|
+
baseUrl: 'https://keycloak.example.com:8443',
|
|
55
|
+
realmName: 'master',
|
|
56
|
+
username: 'admin',
|
|
57
|
+
password: 'admin-password',
|
|
58
|
+
grantType: 'password',
|
|
59
|
+
clientId: 'admin-cli',
|
|
60
|
+
tokenLifeSpan: 60
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log('Authenticated successfully');
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Client Credentials (Service Account)
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
await KeycloakManager.configure({
|
|
70
|
+
baseUrl: 'https://keycloak.example.com:8443',
|
|
71
|
+
realmName: 'master',
|
|
72
|
+
clientId: 'my-service-account',
|
|
73
|
+
clientSecret: 'your-client-secret-here',
|
|
74
|
+
grantType: 'client_credentials',
|
|
75
|
+
tokenLifeSpan: 300
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### With Refresh Token Support
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
await KeycloakManager.configure({
|
|
83
|
+
baseUrl: 'https://keycloak.example.com:8443',
|
|
84
|
+
realmName: 'master',
|
|
85
|
+
username: 'admin',
|
|
86
|
+
password: 'admin',
|
|
87
|
+
grantType: 'password',
|
|
88
|
+
clientId: 'admin-cli',
|
|
89
|
+
scope: 'offline_access', // Request offline access for refresh tokens
|
|
90
|
+
tokenLifeSpan: 60
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Automatic Token Refresh
|
|
95
|
+
|
|
96
|
+
When `tokenLifeSpan` is set, the client automatically refreshes the access token before expiration using an internal timer. The refresh happens at `tokenLifeSpan` seconds interval.
|
|
97
|
+
|
|
98
|
+
### Error Handling
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
try {
|
|
102
|
+
await KeycloakManager.configure({
|
|
103
|
+
baseUrl: 'https://invalid-url',
|
|
104
|
+
realmName: 'master',
|
|
105
|
+
username: 'admin',
|
|
106
|
+
password: 'wrong-password',
|
|
107
|
+
grantType: 'password',
|
|
108
|
+
clientId: 'admin-cli'
|
|
109
|
+
});
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error('Authentication failed:', error.message);
|
|
112
|
+
// Possible errors:
|
|
113
|
+
// - Network errors (connection refused, timeout)
|
|
114
|
+
// - Invalid credentials (401 Unauthorized)
|
|
115
|
+
// - Invalid realm or client (404 Not Found)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## setConfig()
|
|
122
|
+
|
|
123
|
+
Update runtime configuration for the Keycloak Admin Client. Use this to switch realms or update settings after initial configuration.
|
|
124
|
+
|
|
125
|
+
**Syntax:**
|
|
126
|
+
```javascript
|
|
127
|
+
KeycloakManager.setConfig(overrides)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Parameters
|
|
131
|
+
|
|
132
|
+
#### overrides (Object) ⚠️ Required
|
|
133
|
+
|
|
134
|
+
Configuration overrides object.
|
|
135
|
+
|
|
136
|
+
| Property | Type | Required | Description |
|
|
137
|
+
|----------|------|----------|-------------|
|
|
138
|
+
| `realmName` | string | 📋 Optional | Switch to a different realm context |
|
|
139
|
+
| `requestConfig` | object | 📋 Optional | Axios request configuration overrides |
|
|
140
|
+
|
|
141
|
+
### Returns
|
|
142
|
+
|
|
143
|
+
**void** - Synchronous operation
|
|
144
|
+
|
|
145
|
+
### Examples
|
|
146
|
+
|
|
147
|
+
#### Switch Realm Context
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// Initial configuration in master realm
|
|
151
|
+
await KeycloakManager.configure({
|
|
152
|
+
baseUrl: 'https://keycloak.example.com',
|
|
153
|
+
realmName: 'master',
|
|
154
|
+
username: 'admin',
|
|
155
|
+
password: 'admin',
|
|
156
|
+
grantType: 'password',
|
|
157
|
+
clientId: 'admin-cli'
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Now operate on a different realm
|
|
161
|
+
KeycloakManager.setConfig({ realmName: 'my-application-realm' });
|
|
162
|
+
|
|
163
|
+
// All subsequent operations use 'my-application-realm'
|
|
164
|
+
const users = await KeycloakManager.users.find({ max: 100 });
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### Custom Request Configuration
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
KeycloakManager.setConfig({
|
|
171
|
+
realmName: 'my-realm',
|
|
172
|
+
requestConfig: {
|
|
173
|
+
timeout: 10000,
|
|
174
|
+
headers: {
|
|
175
|
+
'X-Custom-Header': 'value'
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Notes
|
|
182
|
+
|
|
183
|
+
- `setConfig()` does NOT re-authenticate. It only updates the context.
|
|
184
|
+
- Changing `realmName` affects all subsequent API calls until changed again.
|
|
185
|
+
- The access token remains valid across realm switches (as long as the authenticated user/service account has permissions).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## getToken()
|
|
190
|
+
|
|
191
|
+
Retrieve the current access token. Useful for debugging or passing the token to other services.
|
|
192
|
+
|
|
193
|
+
**Syntax:**
|
|
194
|
+
```javascript
|
|
195
|
+
const token = await KeycloakManager.getToken()
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Parameters
|
|
199
|
+
|
|
200
|
+
None
|
|
201
|
+
|
|
202
|
+
### Returns
|
|
203
|
+
|
|
204
|
+
**Promise\<string\>** - The current access token (JWT)
|
|
205
|
+
|
|
206
|
+
### Examples
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
await KeycloakManager.configure({
|
|
210
|
+
baseUrl: 'https://keycloak.example.com',
|
|
211
|
+
realmName: 'master',
|
|
212
|
+
username: 'admin',
|
|
213
|
+
password: 'admin',
|
|
214
|
+
grantType: 'password',
|
|
215
|
+
clientId: 'admin-cli'
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const token = await KeycloakManager.getToken();
|
|
219
|
+
console.log('Access Token:', token);
|
|
220
|
+
|
|
221
|
+
// Use token with custom HTTP client
|
|
222
|
+
const axios = require('axios');
|
|
223
|
+
const response = await axios.get('https://keycloak.example.com/admin/realms/master', {
|
|
224
|
+
headers: {
|
|
225
|
+
'Authorization': `Bearer ${token}`
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Notes
|
|
231
|
+
|
|
232
|
+
- The returned token is automatically refreshed by the internal timer (if `tokenLifeSpan` was configured).
|
|
233
|
+
- Token format is JWT (JSON Web Token).
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## auth()
|
|
238
|
+
|
|
239
|
+
Re-authenticate with new or updated credentials. Use this to switch users or refresh authentication manually.
|
|
240
|
+
|
|
241
|
+
**Syntax:**
|
|
242
|
+
```javascript
|
|
243
|
+
await KeycloakManager.auth(credentials)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Parameters
|
|
247
|
+
|
|
248
|
+
#### credentials (Object) ⚠️ Required
|
|
249
|
+
|
|
250
|
+
Same structure as `configure()` credentials parameter.
|
|
251
|
+
|
|
252
|
+
### Returns
|
|
253
|
+
|
|
254
|
+
**Promise\<void\>** - Resolves when re-authentication succeeds
|
|
255
|
+
|
|
256
|
+
### Examples
|
|
257
|
+
|
|
258
|
+
#### Switch User
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
// Initial authentication as admin
|
|
262
|
+
await KeycloakManager.configure({
|
|
263
|
+
baseUrl: 'https://keycloak.example.com',
|
|
264
|
+
realmName: 'master',
|
|
265
|
+
username: 'admin',
|
|
266
|
+
password: 'admin',
|
|
267
|
+
grantType: 'password',
|
|
268
|
+
clientId: 'admin-cli'
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Later, re-authenticate as different user
|
|
272
|
+
await KeycloakManager.auth({
|
|
273
|
+
baseUrl: 'https://keycloak.example.com',
|
|
274
|
+
realmName: 'master',
|
|
275
|
+
username: 'realm-admin',
|
|
276
|
+
password: 'realm-admin-password',
|
|
277
|
+
grantType: 'password',
|
|
278
|
+
clientId: 'admin-cli'
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Refresh Expired Session
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
// If session expired or token invalidated
|
|
286
|
+
try {
|
|
287
|
+
await KeycloakManager.users.find();
|
|
288
|
+
} catch (error) {
|
|
289
|
+
if (error.response && error.response.status === 401) {
|
|
290
|
+
// Re-authenticate
|
|
291
|
+
await KeycloakManager.auth({
|
|
292
|
+
baseUrl: 'https://keycloak.example.com',
|
|
293
|
+
realmName: 'master',
|
|
294
|
+
username: 'admin',
|
|
295
|
+
password: 'admin',
|
|
296
|
+
grantType: 'password',
|
|
297
|
+
clientId: 'admin-cli'
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// Retry operation
|
|
301
|
+
const users = await KeycloakManager.users.find();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Notes
|
|
307
|
+
|
|
308
|
+
- `auth()` stops the existing token refresh timer and starts a new one (if `tokenLifeSpan` is configured).
|
|
309
|
+
- Use `auth()` instead of `configure()` when you need to change credentials without reinitializing handlers.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## stop()
|
|
314
|
+
|
|
315
|
+
Stop the automatic token refresh timer and cleanup resources. Call this when shutting down your application.
|
|
316
|
+
|
|
317
|
+
**Syntax:**
|
|
318
|
+
```javascript
|
|
319
|
+
KeycloakManager.stop()
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Parameters
|
|
323
|
+
|
|
324
|
+
None
|
|
325
|
+
|
|
326
|
+
### Returns
|
|
327
|
+
|
|
328
|
+
**void** - Synchronous operation
|
|
329
|
+
|
|
330
|
+
### Examples
|
|
331
|
+
|
|
332
|
+
#### Application Shutdown
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
const KeycloakManager = require('keycloak-api-manager');
|
|
336
|
+
|
|
337
|
+
async function main() {
|
|
338
|
+
await KeycloakManager.configure({
|
|
339
|
+
baseUrl: 'https://keycloak.example.com',
|
|
340
|
+
realmName: 'master',
|
|
341
|
+
username: 'admin',
|
|
342
|
+
password: 'admin',
|
|
343
|
+
grantType: 'password',
|
|
344
|
+
clientId: 'admin-cli',
|
|
345
|
+
tokenLifeSpan: 60
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// Do work
|
|
349
|
+
const users = await KeycloakManager.users.find({ max: 100 });
|
|
350
|
+
console.log(`Found ${users.length} users`);
|
|
351
|
+
|
|
352
|
+
// Cleanup before exit
|
|
353
|
+
KeycloakManager.stop();
|
|
354
|
+
console.log('Token refresh timer stopped');
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
main().catch(console.error);
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### Process Signal Handlers
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
let cleanupDone = false;
|
|
364
|
+
|
|
365
|
+
process.on('SIGINT', () => {
|
|
366
|
+
if (!cleanupDone) {
|
|
367
|
+
console.log('Shutting down gracefully...');
|
|
368
|
+
KeycloakManager.stop();
|
|
369
|
+
cleanupDone = true;
|
|
370
|
+
process.exit(0);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
process.on('SIGTERM', () => {
|
|
375
|
+
if (!cleanupDone) {
|
|
376
|
+
console.log('Shutting down gracefully...');
|
|
377
|
+
KeycloakManager.stop();
|
|
378
|
+
cleanupDone = true;
|
|
379
|
+
process.exit(0);
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Notes
|
|
385
|
+
|
|
386
|
+
- Always call `stop()` before application exit to prevent dangling timers.
|
|
387
|
+
- After calling `stop()`, you can call `configure()` or `auth()` again to restart.
|
|
388
|
+
- Not calling `stop()` may prevent Node.js process from exiting cleanly.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Full Workflow Example
|
|
393
|
+
|
|
394
|
+
```javascript
|
|
395
|
+
const KeycloakManager = require('keycloak-api-manager');
|
|
396
|
+
|
|
397
|
+
async function keycloakWorkflow() {
|
|
398
|
+
try {
|
|
399
|
+
// 1. Configure and authenticate
|
|
400
|
+
await KeycloakManager.configure({
|
|
401
|
+
baseUrl: 'https://keycloak.example.com:8443',
|
|
402
|
+
realmName: 'master',
|
|
403
|
+
username: 'admin',
|
|
404
|
+
password: 'admin',
|
|
405
|
+
grantType: 'password',
|
|
406
|
+
clientId: 'admin-cli',
|
|
407
|
+
tokenLifeSpan: 60
|
|
408
|
+
});
|
|
409
|
+
console.log('✓ Authenticated');
|
|
410
|
+
|
|
411
|
+
// 2. Work in master realm
|
|
412
|
+
const masterRealms = await KeycloakManager.realms.find();
|
|
413
|
+
console.log(`✓ Found ${masterRealms.length} realms`);
|
|
414
|
+
|
|
415
|
+
// 3. Switch to application realm
|
|
416
|
+
KeycloakManager.setConfig({ realmName: 'my-app' });
|
|
417
|
+
console.log('✓ Switched to my-app realm');
|
|
418
|
+
|
|
419
|
+
// 4. Perform operations
|
|
420
|
+
const users = await KeycloakManager.users.find({ max: 100 });
|
|
421
|
+
console.log(`✓ Found ${users.length} users in my-app`);
|
|
422
|
+
|
|
423
|
+
// 5. Get current token for debugging
|
|
424
|
+
const token = await KeycloakManager.getToken();
|
|
425
|
+
console.log('✓ Current token:', token.substring(0, 50) + '...');
|
|
426
|
+
|
|
427
|
+
// 6. Cleanup
|
|
428
|
+
KeycloakManager.stop();
|
|
429
|
+
console.log('✓ Stopped token refresh');
|
|
430
|
+
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.error('✗ Error:', error.message);
|
|
433
|
+
KeycloakManager.stop();
|
|
434
|
+
process.exit(1);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
keycloakWorkflow();
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## See Also
|
|
444
|
+
|
|
445
|
+
- [API Reference](../api-reference.md) - Complete API documentation index
|
|
446
|
+
- [Realms API](realms.md) - Realm management operations
|
|
447
|
+
- [Users API](users.md) - User management operations
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Groups API
|
|
2
|
+
|
|
3
|
+
Group CRUD, subgroup tree navigation, role mappings, and fine-grained group permissions.
|
|
4
|
+
|
|
5
|
+
**Namespace:** `KeycloakManager.groups`
|
|
6
|
+
|
|
7
|
+
## CRUD and Structure
|
|
8
|
+
|
|
9
|
+
### create(groupRepresentation)
|
|
10
|
+
- **Required**: `groupRepresentation.name` (string)
|
|
11
|
+
- **Optional**: `path`, `attributes`, `subGroups`, `realmRoles`, `clientRoles`
|
|
12
|
+
- **Returns**: Promise<object>
|
|
13
|
+
|
|
14
|
+
### find(filter)
|
|
15
|
+
- **Optional**: `search`, `first`, `max`, `briefRepresentation`, `exact`, `populateHierarchy`
|
|
16
|
+
- **Returns**: Promise<Array<GroupRepresentation>>
|
|
17
|
+
|
|
18
|
+
### findOne(filter)
|
|
19
|
+
- **Required**: `filter.id` (string, group id)
|
|
20
|
+
- **Returns**: Promise<GroupRepresentation>
|
|
21
|
+
|
|
22
|
+
### update(filter, groupRepresentation)
|
|
23
|
+
- **Required**: `filter.id` (string)
|
|
24
|
+
- **Required**: `groupRepresentation` (partial)
|
|
25
|
+
- **Returns**: Promise<void>
|
|
26
|
+
|
|
27
|
+
### del(filter)
|
|
28
|
+
- **Required**: `filter.id` (string)
|
|
29
|
+
- **Returns**: Promise<void>
|
|
30
|
+
|
|
31
|
+
### count(filter)
|
|
32
|
+
- **Optional**: `search`, `top`
|
|
33
|
+
- **Returns**: Promise<number>
|
|
34
|
+
|
|
35
|
+
### listSubGroups(filter)
|
|
36
|
+
- **Required**: `filter.id` (string, parent group id)
|
|
37
|
+
- **Optional**: `search`, `first`, `max`, `briefRepresentation`
|
|
38
|
+
- **Returns**: Promise<Array<GroupRepresentation>>
|
|
39
|
+
|
|
40
|
+
## Realm Role Mappings
|
|
41
|
+
|
|
42
|
+
### addRealmRoleMappings(role_mapping)
|
|
43
|
+
- **Required**: `role_mapping.id` (group id)
|
|
44
|
+
- **Required**: `role_mapping.roles` (Array<{id,name}>)
|
|
45
|
+
- **Returns**: Promise<void>
|
|
46
|
+
|
|
47
|
+
### delRealmRoleMappings(filters)
|
|
48
|
+
- **Required**: `filters.id` (group id)
|
|
49
|
+
- **Required**: `filters.roles` (Array<{id,name}>)
|
|
50
|
+
- **Returns**: Promise<void>
|
|
51
|
+
|
|
52
|
+
### listRoleMappings(filters)
|
|
53
|
+
- **Required**: `filters.id` (group id)
|
|
54
|
+
- **Returns**: Promise<object>
|
|
55
|
+
|
|
56
|
+
### listRealmRoleMappings(filters)
|
|
57
|
+
- **Required**: `filters.id` (group id)
|
|
58
|
+
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
59
|
+
|
|
60
|
+
### listAvailableRealmRoleMappings(filters)
|
|
61
|
+
- **Required**: `filters.id` (group id)
|
|
62
|
+
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
63
|
+
|
|
64
|
+
### listCompositeRealmRoleMappings(filters)
|
|
65
|
+
- **Required**: `filters.id` (group id)
|
|
66
|
+
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
67
|
+
|
|
68
|
+
## Client Role Mappings
|
|
69
|
+
|
|
70
|
+
### addClientRoleMappings(filters)
|
|
71
|
+
- **Required**: `filters.id` (group id)
|
|
72
|
+
- **Required**: `filters.clientUniqueId` (client UUID)
|
|
73
|
+
- **Required**: `filters.roles` (Array<{id,name}>)
|
|
74
|
+
- **Returns**: Promise<void>
|
|
75
|
+
|
|
76
|
+
### delClientRoleMappings(filters)
|
|
77
|
+
- **Required**: `filters.id` (group id)
|
|
78
|
+
- **Required**: `filters.clientUniqueId` (client UUID)
|
|
79
|
+
- **Required**: `filters.roles` (Array<{id,name}>)
|
|
80
|
+
- **Returns**: Promise<void>
|
|
81
|
+
|
|
82
|
+
### listClientRoleMappings(filters)
|
|
83
|
+
- **Required**: `filters.id` (group id)
|
|
84
|
+
- **Required**: `filters.clientUniqueId` (client UUID)
|
|
85
|
+
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
86
|
+
|
|
87
|
+
### listAvailableClientRoleMappings(filters)
|
|
88
|
+
- **Required**: `filters.id` (group id)
|
|
89
|
+
- **Required**: `filters.clientUniqueId` (client UUID)
|
|
90
|
+
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
91
|
+
|
|
92
|
+
### listCompositeClientRoleMappings(filters)
|
|
93
|
+
- **Required**: `filters.id` (group id)
|
|
94
|
+
- **Required**: `filters.clientUniqueId` (client UUID)
|
|
95
|
+
- **Returns**: Promise<Array<RoleRepresentation>>
|
|
96
|
+
|
|
97
|
+
## Fine-Grained Group Permissions (Wrapper Enhancement)
|
|
98
|
+
|
|
99
|
+
These methods wrap Keycloak management-permission endpoints used for group admin authorization.
|
|
100
|
+
|
|
101
|
+
### setPermissions(filters, permissionRepresentation)
|
|
102
|
+
- **Required**: `filters.id` (group id)
|
|
103
|
+
- **Required**: `permissionRepresentation.enabled` (boolean)
|
|
104
|
+
- **Optional**: additional permission fields returned by Keycloak
|
|
105
|
+
- **Returns**: Promise<object>
|
|
106
|
+
|
|
107
|
+
### listPermissions(filters)
|
|
108
|
+
- **Required**: `filters.id` (group id)
|
|
109
|
+
- **Returns**: Promise<object>
|
|
110
|
+
|
|
111
|
+
### Feature Requirement
|
|
112
|
+
Use Keycloak with:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
--features=admin-fine-grained-authz:v1
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Example
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
const group = await KeycloakManager.groups.create({ name: 'engineering' });
|
|
122
|
+
await KeycloakManager.groups.setPermissions({ id: group.id }, { enabled: true });
|
|
123
|
+
const permissions = await KeycloakManager.groups.listPermissions({ id: group.id });
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## See Also
|
|
127
|
+
- [API Reference](../api-reference.md)
|
|
128
|
+
- [Users](users.md)
|
|
129
|
+
- [Roles](roles.md)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Identity Providers API
|
|
2
|
+
|
|
3
|
+
Manage identity providers (OIDC/SAML/social), mappers, import, and permissions.
|
|
4
|
+
|
|
5
|
+
**Namespace:** `KeycloakManager.identityProviders`
|
|
6
|
+
|
|
7
|
+
## Provider CRUD
|
|
8
|
+
|
|
9
|
+
### create(identityProvidersRepresentation)
|
|
10
|
+
- **Required**: `alias`, `providerId`
|
|
11
|
+
- **Optional**: `enabled`, `trustEmail`, `storeToken`, `firstBrokerLoginFlowAlias`, `config`
|
|
12
|
+
- **Returns**: Promise<object>
|
|
13
|
+
|
|
14
|
+
### find()
|
|
15
|
+
- **Params**: none
|
|
16
|
+
- **Returns**: Promise<Array<IdentityProviderRepresentation>>
|
|
17
|
+
|
|
18
|
+
### findOne(filter)
|
|
19
|
+
- **Required**: `filter.alias`
|
|
20
|
+
- **Returns**: Promise<IdentityProviderRepresentation>
|
|
21
|
+
|
|
22
|
+
### update(filter, identityProviderRepresentation)
|
|
23
|
+
- **Required**: `filter.alias`
|
|
24
|
+
- **Required**: updated representation
|
|
25
|
+
- **Returns**: Promise<void>
|
|
26
|
+
|
|
27
|
+
### del(filter)
|
|
28
|
+
- **Required**: `filter.alias`
|
|
29
|
+
- **Returns**: Promise<void>
|
|
30
|
+
|
|
31
|
+
## Factory and Discovery
|
|
32
|
+
|
|
33
|
+
### findFactory(filter)
|
|
34
|
+
- **Required**: `filter.providerId` (example: `oidc`, `saml`, `google`)
|
|
35
|
+
- **Returns**: Promise<object>
|
|
36
|
+
|
|
37
|
+
### importFromUrl(filter)
|
|
38
|
+
- **Required**: provider-specific request payload (typically metadata URL fields)
|
|
39
|
+
- **Returns**: Promise<object>
|
|
40
|
+
|
|
41
|
+
## Mappers
|
|
42
|
+
|
|
43
|
+
### createMapper(mapperParams)
|
|
44
|
+
- **Required**: `mapperParams.identityProviderAlias`
|
|
45
|
+
- **Required**: `mapperParams.name`, `mapperParams.identityProviderMapper`
|
|
46
|
+
- **Optional**: `mapperParams.config`
|
|
47
|
+
- **Returns**: Promise<object>
|
|
48
|
+
|
|
49
|
+
### findMappers(filter)
|
|
50
|
+
- **Required**: `filter.alias` (identity provider alias)
|
|
51
|
+
- **Returns**: Promise<Array<object>>
|
|
52
|
+
|
|
53
|
+
### findOneMapper(filter)
|
|
54
|
+
- **Required**: `filter.alias`
|
|
55
|
+
- **Required**: `filter.id` (mapper id)
|
|
56
|
+
- **Returns**: Promise<object>
|
|
57
|
+
|
|
58
|
+
### updateMapper(filter, mapperRepresentation)
|
|
59
|
+
- **Required**: `filter.alias`
|
|
60
|
+
- **Required**: `filter.id`
|
|
61
|
+
- **Required**: mapper representation
|
|
62
|
+
- **Returns**: Promise<void>
|
|
63
|
+
|
|
64
|
+
### delMapper(filter)
|
|
65
|
+
- **Required**: `filter.alias`
|
|
66
|
+
- **Required**: `filter.id`
|
|
67
|
+
- **Returns**: Promise<void>
|
|
68
|
+
|
|
69
|
+
## Permissions
|
|
70
|
+
|
|
71
|
+
### updatePermission(filter, permissionRepresentation)
|
|
72
|
+
- **Required**: `filter.alias`
|
|
73
|
+
- **Required**: `permissionRepresentation.enabled` (boolean)
|
|
74
|
+
- **Returns**: Promise<object>
|
|
75
|
+
|
|
76
|
+
### listPermissions(filter)
|
|
77
|
+
- **Required**: `filter.alias`
|
|
78
|
+
- **Returns**: Promise<object>
|
|
79
|
+
|
|
80
|
+
## Example
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
await KeycloakManager.identityProviders.create({
|
|
84
|
+
alias: 'google',
|
|
85
|
+
providerId: 'google',
|
|
86
|
+
enabled: true,
|
|
87
|
+
config: {
|
|
88
|
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
|
89
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const mappers = await KeycloakManager.identityProviders.findMappers({ alias: 'google' });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## See Also
|
|
97
|
+
- [API Reference](../api-reference.md)
|
|
98
|
+
- [Organizations](organizations.md)
|