0
# Authorization and Security
1
2
The authorization and security system provides comprehensive Role-Based Access Control (RBAC) using Casbin for fine-grained authorization policies. The system includes AOP-based enforcement, domain-based multi-tenancy, and flexible policy management for securing metadata operations across the LakeSoul ecosystem.
3
4
## Capabilities
5
6
### AuthZEnforcer Class
7
8
The central authorization enforcement class providing Casbin enforcer access and authorization status management.
9
10
```java { .api }
11
/**
12
* Authorization enforcement using Casbin
13
* Provides singleton access to Casbin enforcer and authorization status
14
*/
15
public class AuthZEnforcer {
16
/**
17
* Get Casbin SyncedEnforcer instance
18
* Returns null if authorization is disabled
19
* @return SyncedEnforcer instance or null
20
*/
21
public static SyncedEnforcer get();
22
23
/**
24
* Check if authorization is globally enabled
25
* @return boolean true if authorization is enabled, false otherwise
26
*/
27
public static boolean authZEnabled();
28
}
29
```
30
31
### Authorization Annotations
32
33
Annotation-based authorization for method-level access control with AOP enforcement.
34
35
```java { .api }
36
/**
37
* Method-level authorization annotation
38
* Applied to methods requiring authorization checks
39
*/
40
@Target(ElementType.METHOD)
41
@Retention(RetentionPolicy.RUNTIME)
42
public @interface AuthZ {
43
/**
44
* Authorization value/policy identifier
45
* @return String authorization policy identifier
46
*/
47
String value() default "";
48
49
/**
50
* Object parameter name for authorization
51
* Specifies which method parameter represents the object being accessed
52
* @return String parameter name (default "object")
53
*/
54
String object() default "object";
55
56
/**
57
* Action parameter name for authorization
58
* Specifies which method parameter represents the action being performed
59
* @return String parameter name (default "action")
60
*/
61
String action() default "action";
62
}
63
64
/**
65
* Pre-method authorization annotation
66
* Executed before method invocation
67
*/
68
@Target(ElementType.METHOD)
69
@Retention(RetentionPolicy.RUNTIME)
70
public @interface AuthZBefore {
71
/**
72
* Authorization policy identifier
73
* @return String policy identifier
74
*/
75
String value() default "";
76
77
/**
78
* Object parameter specification
79
* @return String object parameter name
80
*/
81
String object() default "object";
82
83
/**
84
* Action parameter specification
85
* @return String action parameter name
86
*/
87
String action() default "action";
88
}
89
90
/**
91
* Post-method authorization annotation
92
* Executed after method invocation
93
*/
94
@Target(ElementType.METHOD)
95
@Retention(RetentionPolicy.RUNTIME)
96
public @interface AuthZAfter {
97
/**
98
* Authorization policy identifier
99
* @return String policy identifier
100
*/
101
String value() default "";
102
103
/**
104
* Object parameter specification
105
* @return String object parameter name
106
*/
107
String object() default "object";
108
109
/**
110
* Action parameter specification
111
* @return String action parameter name
112
*/
113
String action() default "action";
114
}
115
```
116
117
### Authorization Exception
118
119
Exception class for authorization failures with standardized error handling.
120
121
```java { .api }
122
/**
123
* Exception thrown when access is denied
124
* Extends RuntimeException for unchecked exception handling
125
*/
126
public class AuthZException extends RuntimeException {
127
/**
128
* Create AuthZException with default message
129
* Message: "lakesoul access denied!"
130
*/
131
public AuthZException();
132
133
/**
134
* Create AuthZException with custom message
135
* @param message Custom error message
136
*/
137
public AuthZException(String message);
138
139
/**
140
* Create AuthZException with message and cause
141
* @param message Custom error message
142
* @param cause Root cause exception
143
*/
144
public AuthZException(String message, Throwable cause);
145
}
146
```
147
148
### Authorization Context
149
150
Context management for authorization information including domain and user context.
151
152
```java { .api }
153
/**
154
* Context holder for authorization information
155
* Manages current user domain and authorization state
156
*/
157
public class AuthZContext {
158
/**
159
* Get singleton AuthZContext instance
160
* @return AuthZContext singleton instance
161
*/
162
public static AuthZContext getInstance();
163
164
/**
165
* Get current security domain
166
* @return String current domain name
167
*/
168
public String getDomain();
169
170
/**
171
* Set current security domain
172
* @param domain Domain name to set as current
173
*/
174
public void setDomain(String domain);
175
176
/**
177
* Get current user identifier
178
* @return String current user ID
179
*/
180
public String getUser();
181
182
/**
183
* Set current user identifier
184
* @param user User ID to set as current
185
*/
186
public void setUser(String user);
187
188
/**
189
* Get current user roles
190
* @return List<String> list of role names for current user
191
*/
192
public List<String> getRoles();
193
194
/**
195
* Set current user roles
196
* @param roles List of role names to assign to current user
197
*/
198
public void setRoles(List<String> roles);
199
200
/**
201
* Clear authorization context
202
* Resets user, domain, and roles to default values
203
*/
204
public void clear();
205
}
206
```
207
208
### AOP Authorization Components
209
210
AspectJ-based components for automatic authorization enforcement.
211
212
```java { .api }
213
/**
214
* AOP aspect for authorization enforcement
215
* Intercepts methods annotated with authorization annotations
216
*/
217
public class AuthZAspect {
218
/**
219
* Around advice for @AuthZ annotation
220
* Executes authorization check before method execution
221
* @param joinPoint Method execution join point
222
* @param authZ Authorization annotation
223
* @return Object method result if authorized
224
* @throws AuthZException if access denied
225
*/
226
@Around("@annotation(authZ)")
227
public Object authorizeMethod(ProceedingJoinPoint joinPoint, AuthZ authZ) throws Throwable;
228
229
/**
230
* Before advice for @AuthZBefore annotation
231
* @param joinPoint Method execution join point
232
* @param authZBefore Authorization annotation
233
* @throws AuthZException if access denied
234
*/
235
@Before("@annotation(authZBefore)")
236
public void authorizeBeforeMethod(JoinPoint joinPoint, AuthZBefore authZBefore);
237
238
/**
239
* After advice for @AuthZAfter annotation
240
* @param joinPoint Method execution join point
241
* @param authZAfter Authorization annotation
242
* @throws AuthZException if access denied
243
*/
244
@After("@annotation(authZAfter)")
245
public void authorizeAfterMethod(JoinPoint joinPoint, AuthZAfter authZAfter);
246
}
247
248
/**
249
* AOP advice for authorization operations
250
* Provides common authorization logic for aspects
251
*/
252
public class AuthZAdvice {
253
/**
254
* Perform authorization check
255
* @param subject User or role performing the action
256
* @param object Resource being accessed
257
* @param action Action being performed
258
* @return boolean true if authorized, false otherwise
259
*/
260
public boolean authorize(String subject, String object, String action);
261
262
/**
263
* Extract authorization parameters from method arguments
264
* @param joinPoint Method execution join point
265
* @param authZ Authorization annotation
266
* @return AuthZParameters extracted parameters
267
*/
268
public AuthZParameters extractParameters(JoinPoint joinPoint, AuthZ authZ);
269
}
270
```
271
272
### Authorization Parameter Fetchers
273
274
Flexible parameter extraction system for authorization decisions.
275
276
```java { .api }
277
/**
278
* Base interface for authorization parameter fetchers
279
* Extracts authorization parameters from method calls
280
*/
281
public interface AuthZFetcher {
282
/**
283
* Extract parameter value from method context
284
* @param joinPoint Method execution join point
285
* @param parameterName Name of parameter to extract
286
* @return Object parameter value
287
*/
288
Object fetchParameter(JoinPoint joinPoint, String parameterName);
289
290
/**
291
* Check if this fetcher supports the given parameter
292
* @param parameterName Name of parameter
293
* @return boolean true if supported, false otherwise
294
*/
295
boolean supports(String parameterName);
296
}
297
298
/**
299
* Identity-based authorization parameter fetcher
300
* Extracts user identity information
301
*/
302
public class AuthZIdentFetcher implements AuthZFetcher {
303
/**
304
* Fetch current user identity
305
* @param joinPoint Method execution join point
306
* @param parameterName Parameter name ("user", "subject", etc.)
307
* @return Object user identity
308
*/
309
public Object fetchParameter(JoinPoint joinPoint, String parameterName);
310
311
public boolean supports(String parameterName);
312
}
313
314
/**
315
* Parameter-based authorization fetcher
316
* Extracts values from method parameters
317
*/
318
public class AuthZParamFetcher implements AuthZFetcher {
319
/**
320
* Fetch parameter value from method arguments
321
* @param joinPoint Method execution join point
322
* @param parameterName Name of method parameter
323
* @return Object parameter value
324
*/
325
public Object fetchParameter(JoinPoint joinPoint, String parameterName);
326
327
public boolean supports(String parameterName);
328
}
329
330
/**
331
* Null fetcher for operations without parameters
332
* Returns null for all parameter requests
333
*/
334
public class AuthZNullFetcher implements AuthZFetcher {
335
public Object fetchParameter(JoinPoint joinPoint, String parameterName);
336
public boolean supports(String parameterName);
337
}
338
339
/**
340
* Table read operation parameter fetcher
341
* Specialized for table read authorization
342
*/
343
public class TableReadFetcher implements AuthZFetcher {
344
/**
345
* Extract table-specific parameters for read operations
346
* @param joinPoint Method execution join point
347
* @param parameterName Parameter name ("tableId", "tablePath", etc.)
348
* @return Object table-related parameter value
349
*/
350
public Object fetchParameter(JoinPoint joinPoint, String parameterName);
351
352
public boolean supports(String parameterName);
353
}
354
355
/**
356
* Table write operation parameter fetcher
357
* Specialized for table write authorization
358
*/
359
public class TableWriteFetcher implements AuthZFetcher {
360
/**
361
* Extract table-specific parameters for write operations
362
* @param joinPoint Method execution join point
363
* @param parameterName Parameter name ("tableId", "tablePath", etc.)
364
* @return Object table-related parameter value
365
*/
366
public Object fetchParameter(JoinPoint joinPoint, String parameterName);
367
368
public boolean supports(String parameterName);
369
}
370
```
371
372
**Usage Examples:**
373
374
```java
375
import com.dmetasoul.lakesoul.meta.rbac.*;
376
import com.dmetasoul.lakesoul.meta.entity.TableInfo;
377
import org.casbin.jcasbin.main.SyncedEnforcer;
378
379
public class AuthorizationExample {
380
381
// Method-level authorization using annotations
382
@AuthZ(value = "table_read", object = "tableId", action = "read")
383
public TableInfo getTableInfo(String tableId) {
384
// Method implementation - authorization checked automatically
385
// AuthZ aspect will verify user can read the specified table
386
return loadTableInfo(tableId);
387
}
388
389
@AuthZ(value = "table_write", object = "tableInfo", action = "create")
390
public void createTable(TableInfo tableInfo) {
391
// Authorization checked before table creation
392
// User must have create permission for the table
393
saveTableInfo(tableInfo);
394
}
395
396
@AuthZBefore(value = "namespace_admin", action = "delete")
397
public void deleteNamespace(String namespace) {
398
// Pre-method authorization check
399
// User must have admin permission for namespace operations
400
performNamespaceDeletion(namespace);
401
}
402
403
public void programmaticAuthorizationExample() {
404
// Check if authorization is enabled
405
if (AuthZEnforcer.authZEnabled()) {
406
// Get Casbin enforcer
407
SyncedEnforcer enforcer = AuthZEnforcer.get();
408
409
// Set current user context
410
AuthZContext context = AuthZContext.getInstance();
411
context.setUser("alice");
412
context.setDomain("analytics");
413
context.setRoles(Arrays.asList("analyst", "reader"));
414
415
// Perform authorization check
416
boolean canRead = enforcer.enforce(
417
"alice", // subject (user)
418
"table_001", // object (resource)
419
"read" // action
420
);
421
422
if (canRead) {
423
System.out.println("User authorized to read table");
424
// Proceed with operation
425
} else {
426
throw new AuthZException("Access denied: cannot read table_001");
427
}
428
429
// Check with role-based access
430
boolean canWrite = enforcer.enforce(
431
"analyst", // subject (role)
432
"table_001", // object (resource)
433
"write" // action
434
);
435
436
if (canWrite) {
437
System.out.println("Analyst role authorized to write table");
438
}
439
440
} else {
441
System.out.println("Authorization disabled - allowing all operations");
442
}
443
}
444
445
public void domainBasedAuthorizationExample() {
446
AuthZContext context = AuthZContext.getInstance();
447
448
// Set up analytics domain context
449
context.setUser("data_scientist");
450
context.setDomain("analytics");
451
context.setRoles(Arrays.asList("analyst", "viewer"));
452
453
try {
454
// This will be authorized within analytics domain
455
TableInfo analyticsTable = getTableInfo("analytics_table_001");
456
System.out.println("Access granted to analytics table");
457
458
// Switch to different domain
459
context.setDomain("finance");
460
461
// This may be denied if user doesn't have cross-domain access
462
TableInfo financeTable = getTableInfo("finance_table_001");
463
System.out.println("Access granted to finance table");
464
465
} catch (AuthZException e) {
466
System.err.println("Authorization failed: " + e.getMessage());
467
} finally {
468
// Clear context when done
469
context.clear();
470
}
471
}
472
473
public void configurationExample() {
474
// Check global authorization configuration
475
GlobalConfig config = GlobalConfig.get();
476
477
if (config.isAuthZEnabled()) {
478
System.out.println("Authorization is enabled");
479
System.out.println("Casbin model: " + config.getAuthZCasbinModel());
480
481
// Initialize authorization system
482
initializeAuthorizationPolicies();
483
484
} else {
485
System.out.println("Authorization is disabled");
486
// Skip authorization setup
487
}
488
}
489
490
public void customAuthorizationExample() {
491
SyncedEnforcer enforcer = AuthZEnforcer.get();
492
493
if (enforcer != null) {
494
// Add custom policy rules
495
enforcer.addPolicy("alice", "table_analytics", "read");
496
enforcer.addPolicy("alice", "table_analytics", "write");
497
enforcer.addPolicy("bob", "table_finance", "read");
498
499
// Add role-based policies
500
enforcer.addRoleForUser("alice", "analyst");
501
enforcer.addRoleForUser("bob", "viewer");
502
503
enforcer.addPolicy("analyst", "analytics_domain", "read");
504
enforcer.addPolicy("analyst", "analytics_domain", "write");
505
enforcer.addPolicy("viewer", "all_domains", "read");
506
507
// Save policies (if using file or database adapter)
508
enforcer.savePolicy();
509
510
System.out.println("Custom policies added successfully");
511
}
512
}
513
514
public void errorHandlingExample() {
515
try {
516
// Operation that might fail authorization
517
createTable(buildTableInfo());
518
519
} catch (AuthZException e) {
520
// Handle authorization failure
521
System.err.println("Access denied: " + e.getMessage());
522
523
// Log security event
524
logSecurityEvent("AUTHORIZATION_DENIED",
525
AuthZContext.getInstance().getUser(),
526
"table_create",
527
"table_001");
528
529
// Optionally redirect to access request page
530
redirectToAccessRequest();
531
532
} catch (Exception e) {
533
System.err.println("Unexpected error: " + e.getMessage());
534
e.printStackTrace();
535
}
536
}
537
538
// Helper methods
539
private TableInfo loadTableInfo(String tableId) {
540
// Implementation
541
return null;
542
}
543
544
private void saveTableInfo(TableInfo tableInfo) {
545
// Implementation
546
}
547
548
private void performNamespaceDeletion(String namespace) {
549
// Implementation
550
}
551
552
private TableInfo buildTableInfo() {
553
// Implementation
554
return null;
555
}
556
557
private void initializeAuthorizationPolicies() {
558
// Implementation
559
}
560
561
private void logSecurityEvent(String event, String user, String action, String resource) {
562
// Implementation
563
}
564
565
private void redirectToAccessRequest() {
566
// Implementation
567
}
568
}
569
```
570
571
**Policy Configuration:**
572
573
Authorization policies are configured using Casbin model and policy files:
574
575
**Model Configuration (RBAC with domains):**
576
```ini
577
[request_definition]
578
r = sub, dom, obj, act
579
580
[policy_definition]
581
p = sub, dom, obj, act
582
583
[role_definition]
584
g = _, _, _
585
586
[policy_effect]
587
e = some(where (p.eft == allow))
588
589
[matchers]
590
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
591
```
592
593
**Policy Configuration:**
594
```csv
595
# User policies
596
p, alice, analytics, table_*, read
597
p, alice, analytics, table_*, write
598
p, bob, finance, table_finance_*, read
599
600
# Role policies
601
p, analyst, analytics, table_*, read
602
p, analyst, analytics, table_*, write
603
p, viewer, *, table_*, read
604
605
# Role assignments
606
g, alice, analyst, analytics
607
g, bob, viewer, finance
608
g, charlie, admin, *
609
```
610
611
**Configuration Properties:**
612
613
```properties
614
# Enable/disable authorization
615
lakesoul.authz.enabled=true
616
617
# Casbin model configuration
618
lakesoul.authz.casbin.model=path/to/rbac_with_domains_model.conf
619
620
# Policy storage (file, database, etc.)
621
lakesoul.authz.casbin.policy=path/to/policy.csv
622
623
# Current domain (can be set per user/session)
624
lakesoul.current.domain=analytics
625
```
626
627
**Security Best Practices:**
628
629
1. **Principle of Least Privilege**: Grant minimum necessary permissions
630
2. **Domain Isolation**: Use domains to separate different business units or environments
631
3. **Role-Based Access**: Use roles instead of direct user permissions where possible
632
4. **Audit Logging**: Log all authorization decisions for security monitoring
633
5. **Regular Reviews**: Periodically review and update authorization policies
634
6. **Secure Defaults**: Default to deny access when authorization is enabled
635
7. **Error Handling**: Don't expose sensitive information in authorization error messages
636
637
**Thread Safety:**
638
639
The authorization system is designed for concurrent usage:
640
641
- **Singleton Patterns**: Thread-safe singleton initialization for global components
642
- **Context Management**: Thread-local context storage for user sessions
643
- **Casbin Integration**: SyncedEnforcer provides thread-safe policy enforcement
644
- **AOP Safety**: AspectJ advice execution is thread-safe
645
- **Configuration**: Global configuration is immutable after initialization