0
# Security Context
1
2
Runtime security context management providing access to authentication state, token information, and authorization decisions. These components form the foundation for request-level security operations in Keycloak-secured applications.
3
4
## Capabilities
5
6
### Keycloak Security Context
7
8
Core security context containing authentication and authorization information for the current request.
9
10
```java { .api }
11
/**
12
* Security context containing authentication and authorization information
13
*/
14
public class KeycloakSecurityContext {
15
/**
16
* Get the access token
17
* @return Parsed AccessToken instance
18
*/
19
public AccessToken getToken();
20
21
/**
22
* Get the raw access token string
23
* @return JWT access token string
24
*/
25
public String getTokenString();
26
27
/**
28
* Get the ID token
29
* @return Parsed IDToken instance or null if not available
30
*/
31
public IDToken getIdToken();
32
33
/**
34
* Get the raw ID token string
35
* @return JWT ID token string or null if not available
36
*/
37
public String getIdTokenString();
38
39
/**
40
* Get the refresh token
41
* @return Parsed RefreshToken instance or null if not available
42
*/
43
public RefreshToken getRefreshToken();
44
45
/**
46
* Get the raw refresh token string
47
* @return JWT refresh token string or null if not available
48
*/
49
public String getRefreshTokenString();
50
51
/**
52
* Get the authorization context for permission checking
53
* @return AuthorizationContext instance or null if not available
54
*/
55
public AuthorizationContext getAuthorizationContext();
56
57
/**
58
* Get the realm name
59
* @return Realm identifier
60
*/
61
public String getRealm();
62
63
/**
64
* Check if the security context is active (tokens not expired)
65
* @return true if context is active
66
*/
67
public boolean isActive();
68
69
/**
70
* Get the token category
71
* @return TokenCategory enum value
72
*/
73
public TokenCategory getTokenCategory();
74
}
75
```
76
77
### Authorization Context
78
79
Permission management and authorization decision support for UMA (User-Managed Access) permissions.
80
81
```java { .api }
82
/**
83
* Authorization context for permission checking and UMA support
84
*/
85
public class AuthorizationContext {
86
/**
87
* Check if user has permission for specific resource and scope
88
* @param resource Resource identifier
89
* @param scope Scope identifier
90
* @return true if permission exists
91
*/
92
public boolean hasPermission(String resource, String scope);
93
94
/**
95
* Check if user has permission for specific resource (any scope)
96
* @param resource Resource identifier
97
* @return true if any permission exists for the resource
98
*/
99
public boolean hasResourcePermission(String resource);
100
101
/**
102
* Check if user has permission for specific scope (any resource)
103
* @param scope Scope identifier
104
* @return true if any permission exists for the scope
105
*/
106
public boolean hasScopePermission(String scope);
107
108
/**
109
* Get all permissions for the current user
110
* @return Collection of Permission objects
111
*/
112
public Collection<Permission> getPermissions();
113
114
/**
115
* Get permissions for a specific resource
116
* @param resource Resource identifier
117
* @return Collection of permissions for the resource
118
*/
119
public Collection<Permission> getPermissions(String resource);
120
121
/**
122
* Check if any permissions are granted
123
* @return true if at least one permission is granted
124
*/
125
public boolean isGranted();
126
127
/**
128
* Check if authorization is disabled
129
* @return true if authorization checks are disabled
130
*/
131
public boolean isDisabled();
132
133
/**
134
* Get the authorization token (if available)
135
* @return Authorization token or null
136
*/
137
public String getAuthorizationToken();
138
}
139
140
/**
141
* Individual permission representation
142
*/
143
public class Permission {
144
/**
145
* Get the resource identifier
146
* @return Resource identifier
147
*/
148
public String getResourceId();
149
150
/**
151
* Get the resource name
152
* @return Resource name
153
*/
154
public String getResourceName();
155
156
/**
157
* Get the scopes for this permission
158
* @return Set of scope names
159
*/
160
public Set<String> getScopes();
161
162
/**
163
* Check if permission includes specific scope
164
* @param scope Scope name to check
165
* @return true if scope is included
166
*/
167
public boolean hasScope(String scope);
168
169
/**
170
* Get additional claims for this permission
171
* @return Map of additional claims
172
*/
173
public Map<String, Object> getClaims();
174
175
/**
176
* Get specific claim value
177
* @param name Claim name
178
* @return Claim value or null
179
*/
180
public Object getClaim(String name);
181
}
182
```
183
184
### Keycloak Principal
185
186
Java Principal implementation for authenticated users in Keycloak-secured applications.
187
188
```java { .api }
189
/**
190
* Java Principal implementation for Keycloak authentication
191
* @param <T> Security context type extending KeycloakSecurityContext
192
*/
193
public class KeycloakPrincipal<T extends KeycloakSecurityContext> implements Principal, Serializable {
194
/**
195
* Create principal with security context
196
* @param name Principal name
197
* @param securityContext Keycloak security context
198
*/
199
public KeycloakPrincipal(String name, T securityContext);
200
201
/**
202
* Get the principal name (usually the subject from the token)
203
* @return Principal name
204
*/
205
public String getName();
206
207
/**
208
* Get the Keycloak security context
209
* @return Security context instance
210
*/
211
public T getKeycloakSecurityContext();
212
213
/**
214
* Check equality with another principal
215
* @param obj Object to compare
216
* @return true if principals are equal
217
*/
218
public boolean equals(Object obj);
219
220
/**
221
* Get hash code for the principal
222
* @return Hash code
223
*/
224
public int hashCode();
225
226
/**
227
* Get string representation of the principal
228
* @return String representation
229
*/
230
public String toString();
231
}
232
```
233
234
### Token Store Enumeration
235
236
Token storage mechanisms for different deployment scenarios.
237
238
```java { .api }
239
/**
240
* Token storage type enumeration for different deployment scenarios
241
*/
242
public enum TokenStore {
243
/**
244
* Store tokens in HTTP session (default for web applications)
245
*/
246
SESSION,
247
248
/**
249
* Store tokens in HTTP cookies (for stateless applications)
250
*/
251
COOKIE;
252
253
/**
254
* Get the token store name
255
* @return Token store name in lowercase
256
*/
257
public String getTokenStoreName();
258
}
259
```
260
261
### OAuth Error Handling
262
263
OAuth-specific error exception for authentication and authorization failures.
264
265
```java { .api }
266
/**
267
* OAuth-specific error exception
268
*/
269
public class OAuthErrorException extends Exception {
270
/**
271
* Create OAuth error exception
272
* @param error OAuth error code
273
* @param description Error description
274
*/
275
public OAuthErrorException(String error, String description);
276
277
/**
278
* Create OAuth error exception with cause
279
* @param error OAuth error code
280
* @param description Error description
281
* @param cause Underlying cause
282
*/
283
public OAuthErrorException(String error, String description, Throwable cause);
284
285
/**
286
* Get the OAuth error code
287
* @return Error code (e.g., "invalid_token", "access_denied")
288
*/
289
public String getError();
290
291
/**
292
* Get the error description
293
* @return Human-readable error description
294
*/
295
public String getDescription();
296
297
/**
298
* Get the error URI (if available)
299
* @return Error URI or null
300
*/
301
public String getErrorUri();
302
}
303
```
304
305
### Abstract OAuth Client
306
307
Base implementation for OAuth clients with common functionality.
308
309
```java { .api }
310
/**
311
* Abstract base class for OAuth client implementations
312
*/
313
public abstract class AbstractOAuthClient {
314
/**
315
* Get the client ID
316
* @return Client identifier
317
*/
318
public String getClientId();
319
320
/**
321
* Set the client ID
322
* @param clientId Client identifier
323
*/
324
public void setClientId(String clientId);
325
326
/**
327
* Get the client secret
328
* @return Client secret
329
*/
330
public String getClientSecret();
331
332
/**
333
* Set the client secret
334
* @param clientSecret Client secret
335
*/
336
public void setClientSecret(String clientSecret);
337
338
/**
339
* Get the auth server URL
340
* @return Authorization server URL
341
*/
342
public String getAuthUrl();
343
344
/**
345
* Set the auth server URL
346
* @param authUrl Authorization server URL
347
*/
348
public void setAuthUrl(String authUrl);
349
350
/**
351
* Get the token endpoint URL
352
* @return Token endpoint URL
353
*/
354
public String getTokenUrl();
355
356
/**
357
* Set the token endpoint URL
358
* @param tokenUrl Token endpoint URL
359
*/
360
public void setTokenUrl(String tokenUrl);
361
362
/**
363
* Get the redirect URI
364
* @return Redirect URI
365
*/
366
public String getRedirectUri();
367
368
/**
369
* Set the redirect URI
370
* @param redirectUri Redirect URI
371
*/
372
public void setRedirectUri(String redirectUri);
373
374
/**
375
* Get the requested scope
376
* @return Space-separated scope values
377
*/
378
public String getScope();
379
380
/**
381
* Set the requested scope
382
* @param scope Space-separated scope values
383
*/
384
public void setScope(String scope);
385
386
/**
387
* Check if HTTPS is required
388
* @return true if HTTPS required
389
*/
390
public boolean isHttpsRequired();
391
392
/**
393
* Set HTTPS required flag
394
* @param httpsRequired HTTPS required flag
395
*/
396
public void setHttpsRequired(boolean httpsRequired);
397
398
/**
399
* Generate authorization URL
400
* @param state State parameter for CSRF protection
401
* @return Authorization URL
402
*/
403
public abstract String generateAuthUrl(String state);
404
405
/**
406
* Exchange authorization code for tokens
407
* @param code Authorization code
408
* @return Access token response
409
* @throws OAuthErrorException if token exchange fails
410
*/
411
public abstract AccessTokenResponse exchangeCodeForToken(String code) throws OAuthErrorException;
412
413
/**
414
* Refresh access token using refresh token
415
* @param refreshToken Refresh token
416
* @return New access token response
417
* @throws OAuthErrorException if token refresh fails
418
*/
419
public abstract AccessTokenResponse refreshToken(String refreshToken) throws OAuthErrorException;
420
}
421
```
422
423
## Usage Examples
424
425
```java
426
import org.keycloak.*;
427
import org.keycloak.representations.*;
428
import javax.servlet.http.HttpServletRequest;
429
430
// Working with KeycloakSecurityContext
431
public class SecureController {
432
433
public void handleSecureRequest(HttpServletRequest request) {
434
// Get security context from request
435
KeycloakSecurityContext securityContext =
436
(KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
437
438
if (securityContext != null && securityContext.isActive()) {
439
// Access token information
440
AccessToken token = securityContext.getToken();
441
String subject = token.getSubject();
442
String realm = securityContext.getRealm();
443
444
// Check roles
445
AccessToken.Access realmAccess = token.getRealmAccess();
446
if (realmAccess != null && realmAccess.isUserInRole("admin")) {
447
// Handle admin access
448
handleAdminRequest(securityContext);
449
}
450
451
// Check client-specific roles
452
AccessToken.Access clientAccess = token.getResourceAccess("my-app");
453
if (clientAccess != null && clientAccess.isUserInRole("manager")) {
454
// Handle manager access
455
handleManagerRequest(securityContext);
456
}
457
458
// Work with ID token if available
459
IDToken idToken = securityContext.getIdToken();
460
if (idToken != null) {
461
String email = idToken.getEmail();
462
String name = idToken.getName();
463
// Use profile information
464
updateUserProfile(email, name);
465
}
466
}
467
}
468
469
private void handleAdminRequest(KeycloakSecurityContext context) {
470
// Check authorization permissions
471
AuthorizationContext authz = context.getAuthorizationContext();
472
if (authz != null) {
473
// Check specific resource permissions
474
if (authz.hasPermission("user-management", "read")) {
475
// Allow reading user data
476
}
477
478
if (authz.hasPermission("user-management", "write")) {
479
// Allow modifying user data
480
}
481
482
// Get all permissions
483
Collection<Permission> permissions = authz.getPermissions();
484
for (Permission permission : permissions) {
485
String resourceName = permission.getResourceName();
486
Set<String> scopes = permission.getScopes();
487
// Process permissions
488
}
489
}
490
}
491
492
private void handleManagerRequest(KeycloakSecurityContext context) {
493
AccessToken token = context.getToken();
494
495
// Check token expiration
496
if (token.isExpired()) {
497
// Handle token refresh or re-authentication
498
handleTokenExpiration(context);
499
return;
500
}
501
502
// Check specific permissions
503
AuthorizationContext authz = context.getAuthorizationContext();
504
if (authz != null && authz.hasResourcePermission("project-data")) {
505
// Allow access to project data
506
allowProjectAccess();
507
}
508
}
509
510
private void handleTokenExpiration(KeycloakSecurityContext context) {
511
// Check if refresh token is available
512
RefreshToken refreshToken = context.getRefreshToken();
513
if (refreshToken != null && !refreshToken.isExpired()) {
514
// Initiate token refresh
515
initiateTokenRefresh(context.getRefreshTokenString());
516
} else {
517
// Redirect to authentication
518
redirectToLogin();
519
}
520
}
521
}
522
523
// Working with KeycloakPrincipal
524
public class PrincipalExample {
525
526
public void handlePrincipal(Principal principal) {
527
if (principal instanceof KeycloakPrincipal) {
528
KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) principal;
529
KeycloakSecurityContext context = keycloakPrincipal.getKeycloakSecurityContext();
530
531
// Get user information
532
AccessToken token = context.getToken();
533
String username = token.getPreferredUsername();
534
String email = token.getEmail();
535
536
// Log user activity
537
logUserActivity(username, "Accessed secure resource");
538
}
539
}
540
}
541
542
// OAuth client implementation
543
public class MyOAuthClient extends AbstractOAuthClient {
544
545
@Override
546
public String generateAuthUrl(String state) {
547
StringBuilder url = new StringBuilder(getAuthUrl());
548
url.append("?response_type=code");
549
url.append("&client_id=").append(getClientId());
550
url.append("&redirect_uri=").append(getRedirectUri());
551
url.append("&scope=").append(getScope());
552
url.append("&state=").append(state);
553
return url.toString();
554
}
555
556
@Override
557
public AccessTokenResponse exchangeCodeForToken(String code) throws OAuthErrorException {
558
// Implementation for token exchange
559
// Make HTTP POST to token endpoint
560
// Parse response and return AccessTokenResponse
561
// Throw OAuthErrorException on error
562
return null; // Implementation would return actual response
563
}
564
565
@Override
566
public AccessTokenResponse refreshToken(String refreshToken) throws OAuthErrorException {
567
// Implementation for token refresh
568
// Make HTTP POST to token endpoint with refresh_token grant
569
// Parse response and return AccessTokenResponse
570
// Throw OAuthErrorException on error
571
return null; // Implementation would return actual response
572
}
573
}
574
575
// Error handling
576
public class ErrorHandlingExample {
577
578
public void handleOAuthError() {
579
try {
580
// OAuth operation that might fail
581
performOAuthOperation();
582
} catch (OAuthErrorException e) {
583
String errorCode = e.getError();
584
String description = e.getDescription();
585
586
switch (errorCode) {
587
case "invalid_token":
588
// Handle invalid token
589
handleInvalidToken(description);
590
break;
591
case "access_denied":
592
// Handle access denied
593
handleAccessDenied(description);
594
break;
595
case "invalid_grant":
596
// Handle invalid grant
597
handleInvalidGrant(description);
598
break;
599
default:
600
// Handle unknown error
601
handleUnknownError(errorCode, description);
602
}
603
}
604
}
605
}
606
```