0
# Authentication & Security
1
2
Kerberos authentication support and security utilities for secure communication and credential management. This module provides comprehensive security infrastructure including Kerberos integration, secure client login mechanisms, credential management, and authentication context handling for enterprise security environments.
3
4
## Capabilities
5
6
### SecureClientLogin
7
8
Core utility class providing Kerberos authentication and secure login functionality for Ranger components.
9
10
```java { .api }
11
/**
12
* Utility class for secure client authentication using Kerberos
13
*/
14
public class SecureClientLogin {
15
/**
16
* Hostname placeholder for principal names that gets replaced with actual hostname
17
*/
18
public static final String HOSTNAME_PATTERN = "_HOST";
19
20
/**
21
* Login user from keytab file using Kerberos authentication
22
* @param user - Principal name (may contain _HOST placeholder)
23
* @param path - Path to keytab file
24
* @return Subject with Kerberos credentials
25
* @throws IOException if login fails or keytab is invalid
26
*/
27
public static Subject loginUserFromKeytab(String user, String path) throws IOException;
28
29
/**
30
* Login user from keytab file with custom name rules
31
* @param user - Principal name (may contain _HOST placeholder)
32
* @param path - Path to keytab file
33
* @param nameRules - Custom Kerberos name rules for principal mapping
34
* @return Subject with Kerberos credentials
35
* @throws IOException if login fails or keytab is invalid
36
*/
37
public static Subject loginUserFromKeytab(String user, String path, String nameRules) throws IOException;
38
39
/**
40
* Login user with username and password
41
* @param user - Username for authentication
42
* @param password - Password for authentication
43
* @return Subject with authentication credentials
44
* @throws IOException if authentication fails
45
*/
46
public static Subject loginUserWithPassword(String user, String password) throws IOException;
47
48
/**
49
* Login using current user context (from system properties or environment)
50
* @param user - Username to login as
51
* @return Subject with current user credentials
52
* @throws IOException if login fails
53
*/
54
public static Subject login(String user) throws IOException;
55
56
/**
57
* Get user principals from an authenticated subject
58
* @param subject - Authenticated subject
59
* @return Set of user principals
60
*/
61
public static Set<Principal> getUserPrincipals(Subject subject);
62
63
/**
64
* Create a user principal for the given login name
65
* @param loginName - Login name to create principal for
66
* @return User principal object
67
*/
68
public static Principal createUserPrincipal(String loginName);
69
70
/**
71
* Check if Kerberos credentials exist for the specified principal and keytab
72
* @param principal - Kerberos principal name
73
* @param keytabPath - Path to keytab file
74
* @return True if valid Kerberos credentials exist
75
*/
76
public static boolean isKerberosCredentialExists(String principal, String keytabPath);
77
78
/**
79
* Get the actual principal name by replacing _HOST with actual hostname
80
* @param principalConfig - Principal configuration (may contain _HOST)
81
* @param hostName - Hostname to substitute for _HOST
82
* @return Resolved principal name
83
* @throws IOException if hostname resolution fails
84
*/
85
public static String getPrincipal(String principalConfig, String hostName) throws IOException;
86
87
/**
88
* Get the current hostname for principal name resolution
89
* @return Current hostname
90
* @throws IOException if hostname cannot be determined
91
*/
92
public static String getHostname() throws IOException;
93
94
/**
95
* Validate keytab file and principal combination
96
* @param principal - Kerberos principal
97
* @param keytabPath - Path to keytab file
98
* @return True if keytab contains valid credentials for principal
99
*/
100
public static boolean validateKeytab(String principal, String keytabPath);
101
102
/**
103
* Refresh Kerberos credentials for a subject
104
* @param subject - Subject to refresh credentials for
105
* @return Refreshed subject with new credentials
106
* @throws IOException if credential refresh fails
107
*/
108
public static Subject refreshCredentials(Subject subject) throws IOException;
109
}
110
```
111
112
### KrbPasswordSaverLoginModule
113
114
Custom Kerberos login module that securely handles password-based authentication while integrating with the Java security framework.
115
116
```java { .api }
117
/**
118
* Custom Kerberos login module for password-based authentication
119
* Implements the standard JAAS LoginModule interface
120
*/
121
public class KrbPasswordSaverLoginModule implements LoginModule {
122
/**
123
* Configuration parameter name for username
124
*/
125
public static final String USERNAME_PARAM = "javax.security.auth.login.name";
126
127
/**
128
* Configuration parameter name for password
129
*/
130
public static final String PASSWORD_PARAM = "javax.security.auth.login.password";
131
132
/**
133
* Configuration parameter for debug mode
134
*/
135
public static final String DEBUG_PARAM = "debug";
136
137
/**
138
* Configuration parameter for storing password in shared state
139
*/
140
public static final String STORE_PASSWORD_PARAM = "storePassword";
141
142
/**
143
* Configuration parameter for clearing password after use
144
*/
145
public static final String CLEAR_PASS_PARAM = "clearPass";
146
147
/**
148
* Default constructor for login module
149
*/
150
public KrbPasswordSaverLoginModule();
151
152
/**
153
* Initialize the login module
154
* @param subject - Subject to be authenticated
155
* @param callbackhandler - Handler for authentication callbacks
156
* @param sharedMap - Shared state between login modules
157
* @param options - Configuration options for this login module
158
*/
159
public void initialize(Subject subject, CallbackHandler callbackhandler,
160
Map<String, ?> sharedMap, Map<String, ?> options);
161
162
/**
163
* Perform the authentication login
164
* @return True if authentication succeeds
165
* @throws LoginException if authentication fails
166
*/
167
public boolean login() throws LoginException;
168
169
/**
170
* Commit the authentication (add principals and credentials to subject)
171
* @return True if commit succeeds
172
* @throws LoginException if commit fails
173
*/
174
public boolean commit() throws LoginException;
175
176
/**
177
* Abort the authentication process
178
* @return True if abort succeeds
179
* @throws LoginException if abort fails
180
*/
181
public boolean abort() throws LoginException;
182
183
/**
184
* Logout and remove principals/credentials from subject
185
* @return True if logout succeeds
186
* @throws LoginException if logout fails
187
*/
188
public boolean logout() throws LoginException;
189
190
/**
191
* Check if debug mode is enabled
192
* @return True if debug logging is enabled
193
*/
194
public boolean isDebugEnabled();
195
196
/**
197
* Get the authenticated username
198
* @return Username from authentication
199
*/
200
public String getUsername();
201
202
/**
203
* Clear stored password from memory
204
*/
205
public void clearPassword();
206
}
207
```
208
209
### Authentication Context Management
210
211
Classes for managing authentication context and credentials in multi-threaded environments.
212
213
```java { .api }
214
/**
215
* Authentication context manager for thread-safe credential handling
216
*/
217
public class RangerAuthenticationContext {
218
/**
219
* Set authentication context for current thread
220
* @param subject - Authenticated subject
221
*/
222
public static void setCurrentSubject(Subject subject);
223
224
/**
225
* Get authentication context for current thread
226
* @return Current authenticated subject or null
227
*/
228
public static Subject getCurrentSubject();
229
230
/**
231
* Clear authentication context for current thread
232
*/
233
public static void clearCurrentSubject();
234
235
/**
236
* Execute privileged action with authenticated subject
237
* @param action - Action to execute
238
* @param subject - Subject to use for execution
239
* @return Result of privileged action
240
* @throws Exception if action execution fails
241
*/
242
public static <T> T doAsPrivileged(PrivilegedExceptionAction<T> action, Subject subject) throws Exception;
243
244
/**
245
* Check if current thread has valid authentication context
246
* @return True if authenticated context exists
247
*/
248
public static boolean isAuthenticated();
249
250
/**
251
* Get current user principal name
252
* @return Principal name or null if not authenticated
253
*/
254
public static String getCurrentUserName();
255
256
/**
257
* Get current user's group memberships
258
* @return Set of group names
259
*/
260
public static Set<String> getCurrentUserGroups();
261
}
262
263
/**
264
* Credential manager for secure handling of authentication credentials
265
*/
266
public class RangerCredentialManager {
267
/**
268
* Store credentials securely in memory
269
* @param alias - Credential alias/identifier
270
* @param credential - Credential to store
271
*/
272
public void storeCredential(String alias, char[] credential);
273
274
/**
275
* Retrieve stored credentials
276
* @param alias - Credential alias/identifier
277
* @return Stored credential or null if not found
278
*/
279
public char[] getCredential(String alias);
280
281
/**
282
* Remove credentials from secure storage
283
* @param alias - Credential alias/identifier
284
* @return True if credential was removed
285
*/
286
public boolean removeCredential(String alias);
287
288
/**
289
* Clear all stored credentials
290
*/
291
public void clearAllCredentials();
292
293
/**
294
* Check if credential exists
295
* @param alias - Credential alias/identifier
296
* @return True if credential is stored
297
*/
298
public boolean hasCredential(String alias);
299
300
/**
301
* Get list of stored credential aliases
302
* @return Set of credential aliases
303
*/
304
public Set<String> getCredentialAliases();
305
}
306
307
/**
308
* Security utilities for Ranger components
309
*/
310
public class RangerSecurityUtils {
311
/**
312
* Encrypt sensitive data using configured encryption
313
* @param data - Data to encrypt
314
* @param key - Encryption key
315
* @return Encrypted data
316
*/
317
public static byte[] encrypt(byte[] data, String key);
318
319
/**
320
* Decrypt sensitive data using configured decryption
321
* @param encryptedData - Data to decrypt
322
* @param key - Decryption key
323
* @return Decrypted data
324
*/
325
public static byte[] decrypt(byte[] encryptedData, String key);
326
327
/**
328
* Generate secure random password
329
* @param length - Password length
330
* @return Generated password
331
*/
332
public static char[] generateSecurePassword(int length);
333
334
/**
335
* Hash password using secure hashing algorithm
336
* @param password - Password to hash
337
* @param salt - Salt for hashing
338
* @return Hashed password
339
*/
340
public static String hashPassword(char[] password, byte[] salt);
341
342
/**
343
* Verify password against hash
344
* @param password - Password to verify
345
* @param hash - Hash to verify against
346
* @param salt - Salt used for hashing
347
* @return True if password matches hash
348
*/
349
public static boolean verifyPassword(char[] password, String hash, byte[] salt);
350
351
/**
352
* Generate cryptographic salt
353
* @return Random salt bytes
354
*/
355
public static byte[] generateSalt();
356
}
357
```
358
359
### SSL/TLS Security Configuration
360
361
Classes for configuring SSL/TLS security for Ranger communications.
362
363
```java { .api }
364
/**
365
* SSL configuration and utilities for secure communications
366
*/
367
public class RangerSSLConfig {
368
/**
369
* Configuration key for SSL enabled flag
370
*/
371
public static final String SSL_ENABLED = "ranger.ssl.enabled";
372
373
/**
374
* Configuration key for keystore path
375
*/
376
public static final String KEYSTORE_PATH = "ranger.ssl.keystore.file";
377
378
/**
379
* Configuration key for keystore password
380
*/
381
public static final String KEYSTORE_PASSWORD = "ranger.ssl.keystore.password";
382
383
/**
384
* Configuration key for truststore path
385
*/
386
public static final String TRUSTSTORE_PATH = "ranger.ssl.truststore.file";
387
388
/**
389
* Configuration key for truststore password
390
*/
391
public static final String TRUSTSTORE_PASSWORD = "ranger.ssl.truststore.password";
392
393
/**
394
* Initialize SSL configuration from properties
395
* @param config - Configuration properties
396
*/
397
public void init(Configuration config);
398
399
/**
400
* Check if SSL is enabled
401
* @return True if SSL is enabled
402
*/
403
public boolean isSSLEnabled();
404
405
/**
406
* Get SSL context for secure communications
407
* @return Configured SSL context
408
* @throws Exception if SSL context creation fails
409
*/
410
public SSLContext getSSLContext() throws Exception;
411
412
/**
413
* Create SSL socket factory
414
* @return SSL socket factory
415
* @throws Exception if factory creation fails
416
*/
417
public SSLSocketFactory createSSLSocketFactory() throws Exception;
418
419
/**
420
* Create trust manager for certificate validation
421
* @return Array of trust managers
422
* @throws Exception if trust manager creation fails
423
*/
424
public TrustManager[] createTrustManagers() throws Exception;
425
426
/**
427
* Create key manager for client certificates
428
* @return Array of key managers
429
* @throws Exception if key manager creation fails
430
*/
431
public KeyManager[] createKeyManagers() throws Exception;
432
433
/**
434
* Validate SSL configuration
435
* @return True if configuration is valid
436
*/
437
public boolean validateConfiguration();
438
}
439
```
440
441
**Usage Examples:**
442
443
```java
444
import org.apache.hadoop.security.SecureClientLogin;
445
import org.apache.hadoop.security.KrbPasswordSaverLoginModule;
446
import javax.security.auth.Subject;
447
import java.security.PrivilegedExceptionAction;
448
449
// Kerberos authentication with keytab
450
public class KerberosAuthenticationExample {
451
public void authenticateWithKeytab() {
452
try {
453
// Define Kerberos principal and keytab path
454
String principal = "ranger/hostname@EXAMPLE.COM";
455
String keytabPath = "/etc/security/keytabs/ranger.keytab";
456
457
// Check if credentials exist before attempting login
458
if (!SecureClientLogin.isKerberosCredentialExists(principal, keytabPath)) {
459
throw new IOException("Kerberos credentials not found for " + principal);
460
}
461
462
// Resolve hostname in principal if needed
463
String resolvedPrincipal = SecureClientLogin.getPrincipal(
464
"ranger/_HOST@EXAMPLE.COM",
465
SecureClientLogin.getHostname()
466
);
467
468
// Perform keytab-based login
469
Subject subject = SecureClientLogin.loginUserFromKeytab(resolvedPrincipal, keytabPath);
470
471
// Set authentication context
472
RangerAuthenticationContext.setCurrentSubject(subject);
473
474
// Execute privileged operations
475
String result = RangerAuthenticationContext.doAsPrivileged(
476
new PrivilegedExceptionAction<String>() {
477
@Override
478
public String run() throws Exception {
479
// Perform authenticated operations here
480
return "Authenticated operation completed";
481
}
482
},
483
subject
484
);
485
486
System.out.println("Operation result: " + result);
487
488
// Get authentication info
489
Set<Principal> principals = SecureClientLogin.getUserPrincipals(subject);
490
for (Principal p : principals) {
491
System.out.println("Authenticated as: " + p.getName());
492
}
493
494
} catch (IOException e) {
495
System.err.println("Kerberos authentication failed: " + e.getMessage());
496
} finally {
497
// Clear authentication context
498
RangerAuthenticationContext.clearCurrentSubject();
499
}
500
}
501
}
502
503
// Password-based authentication using JAAS
504
public class PasswordAuthenticationExample {
505
public void authenticateWithPassword() {
506
try {
507
// Configure JAAS login context
508
Configuration jaasConfig = new Configuration() {
509
@Override
510
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
511
Map<String, String> options = new HashMap<>();
512
options.put("debug", "true");
513
options.put("storePassword", "true");
514
options.put("clearPass", "false");
515
516
return new AppConfigurationEntry[] {
517
new AppConfigurationEntry(
518
"org.apache.hadoop.security.KrbPasswordSaverLoginModule",
519
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
520
options
521
)
522
};
523
}
524
};
525
526
Configuration.setConfiguration(jaasConfig);
527
528
// Create login context
529
LoginContext loginContext = new LoginContext("RangerAuth", new CallbackHandler() {
530
@Override
531
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
532
for (Callback callback : callbacks) {
533
if (callback instanceof NameCallback) {
534
((NameCallback) callback).setName("alice@EXAMPLE.COM");
535
} else if (callback instanceof PasswordCallback) {
536
((PasswordCallback) callback).setPassword("password123".toCharArray());
537
}
538
}
539
}
540
});
541
542
// Perform login
543
loginContext.login();
544
Subject subject = loginContext.getSubject();
545
546
// Use authenticated subject
547
RangerAuthenticationContext.setCurrentSubject(subject);
548
549
System.out.println("Password authentication successful");
550
System.out.println("Current user: " + RangerAuthenticationContext.getCurrentUserName());
551
552
} catch (LoginException e) {
553
System.err.println("Password authentication failed: " + e.getMessage());
554
}
555
}
556
}
557
558
// Credential management example
559
public class CredentialManagementExample {
560
public void manageCredentials() {
561
RangerCredentialManager credManager = new RangerCredentialManager();
562
563
// Store credentials securely
564
char[] dbPassword = "database_password_123".toCharArray();
565
credManager.storeCredential("database.password", dbPassword);
566
567
char[] apiKey = "api_key_xyz789".toCharArray();
568
credManager.storeCredential("external.api.key", apiKey);
569
570
// Retrieve credentials when needed
571
char[] retrievedPassword = credManager.getCredential("database.password");
572
if (retrievedPassword != null) {
573
System.out.println("Database password retrieved: " + new String(retrievedPassword));
574
575
// Clear password from memory after use
576
Arrays.fill(retrievedPassword, '\0');
577
}
578
579
// List all stored credentials
580
Set<String> aliases = credManager.getCredentialAliases();
581
System.out.println("Stored credentials: " + aliases);
582
583
// Remove specific credential
584
credManager.removeCredential("external.api.key");
585
586
// Clear all credentials on shutdown
587
credManager.clearAllCredentials();
588
}
589
}
590
591
// SSL configuration example
592
public class SSLConfigurationExample {
593
public void configureSSL() {
594
try {
595
// Create configuration with SSL settings
596
Configuration config = new Configuration();
597
config.set(RangerSSLConfig.SSL_ENABLED, "true");
598
config.set(RangerSSLConfig.KEYSTORE_PATH, "/etc/security/keystores/ranger.jks");
599
config.set(RangerSSLConfig.KEYSTORE_PASSWORD, "keystore_password");
600
config.set(RangerSSLConfig.TRUSTSTORE_PATH, "/etc/security/truststores/truststore.jks");
601
config.set(RangerSSLConfig.TRUSTSTORE_PASSWORD, "truststore_password");
602
603
// Initialize SSL configuration
604
RangerSSLConfig sslConfig = new RangerSSLConfig();
605
sslConfig.init(config);
606
607
// Validate configuration
608
if (!sslConfig.validateConfiguration()) {
609
throw new Exception("Invalid SSL configuration");
610
}
611
612
if (sslConfig.isSSLEnabled()) {
613
// Get SSL context for secure communications
614
SSLContext sslContext = sslConfig.getSSLContext();
615
616
// Create SSL socket factory
617
SSLSocketFactory socketFactory = sslConfig.createSSLSocketFactory();
618
619
// Use SSL context for HTTPS connections
620
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
621
622
System.out.println("SSL configuration successful");
623
}
624
625
} catch (Exception e) {
626
System.err.println("SSL configuration failed: " + e.getMessage());
627
}
628
}
629
}
630
631
// Security utilities usage
632
public class SecurityUtilitiesExample {
633
public void useSecurityUtils() {
634
try {
635
// Generate secure password
636
char[] password = RangerSecurityUtils.generateSecurePassword(16);
637
System.out.println("Generated password length: " + password.length);
638
639
// Hash password with salt
640
byte[] salt = RangerSecurityUtils.generateSalt();
641
String hashedPassword = RangerSecurityUtils.hashPassword(password, salt);
642
System.out.println("Password hashed successfully");
643
644
// Verify password
645
boolean isValid = RangerSecurityUtils.verifyPassword(password, hashedPassword, salt);
646
System.out.println("Password verification: " + isValid);
647
648
// Encrypt sensitive data
649
String sensitiveData = "confidential information";
650
byte[] encrypted = RangerSecurityUtils.encrypt(
651
sensitiveData.getBytes(),
652
"encryption_key_123"
653
);
654
System.out.println("Data encrypted, length: " + encrypted.length);
655
656
// Decrypt data
657
byte[] decrypted = RangerSecurityUtils.decrypt(encrypted, "encryption_key_123");
658
String decryptedText = new String(decrypted);
659
System.out.println("Decrypted data: " + decryptedText);
660
661
// Clear password from memory
662
Arrays.fill(password, '\0');
663
664
} catch (Exception e) {
665
System.err.println("Security operations failed: " + e.getMessage());
666
}
667
}
668
}
669
670
// Complete authentication workflow
671
public class AuthenticationWorkflowExample {
672
public void completeAuthenticationWorkflow() {
673
try {
674
// Step 1: Initialize SSL configuration
675
Configuration config = new Configuration();
676
config.set("ranger.ssl.enabled", "true");
677
// ... other SSL settings
678
679
RangerSSLConfig sslConfig = new RangerSSLConfig();
680
sslConfig.init(config);
681
682
// Step 2: Authenticate with Kerberos
683
String principal = "ranger/service@EXAMPLE.COM";
684
String keytab = "/etc/security/keytabs/ranger.keytab";
685
686
Subject subject = SecureClientLogin.loginUserFromKeytab(principal, keytab);
687
RangerAuthenticationContext.setCurrentSubject(subject);
688
689
// Step 3: Store additional credentials securely
690
RangerCredentialManager credManager = new RangerCredentialManager();
691
credManager.storeCredential("db.password", "db_pass_123".toCharArray());
692
693
// Step 4: Perform authenticated operations
694
if (RangerAuthenticationContext.isAuthenticated()) {
695
String currentUser = RangerAuthenticationContext.getCurrentUserName();
696
Set<String> groups = RangerAuthenticationContext.getCurrentUserGroups();
697
698
System.out.println("Authenticated user: " + currentUser);
699
System.out.println("User groups: " + groups);
700
701
// Execute privileged operations
702
RangerAuthenticationContext.doAsPrivileged(
703
new PrivilegedExceptionAction<Void>() {
704
@Override
705
public Void run() throws Exception {
706
// Perform secure operations here
707
System.out.println("Executing privileged operation");
708
return null;
709
}
710
},
711
subject
712
);
713
}
714
715
} catch (Exception e) {
716
System.err.println("Authentication workflow failed: " + e.getMessage());
717
} finally {
718
// Cleanup
719
RangerAuthenticationContext.clearCurrentSubject();
720
}
721
}
722
}
723
```
724
725
## Security Best Practices
726
727
### Credential Management
728
- **Never store passwords in plain text**: Use secure credential storage mechanisms
729
- **Clear sensitive data**: Always clear passwords and credentials from memory after use
730
- **Use secure random generation**: For passwords, salts, and encryption keys
731
- **Implement credential rotation**: Regularly rotate stored credentials
732
733
### Kerberos Authentication
734
- **Secure keytab storage**: Protect keytab files with appropriate file permissions (600)
735
- **Principal validation**: Validate Kerberos principals before authentication attempts
736
- **Credential refresh**: Implement automatic ticket refresh for long-running services
737
- **Error handling**: Provide meaningful error messages without exposing sensitive information
738
739
### SSL/TLS Configuration
740
- **Use strong protocols**: Disable weak SSL/TLS versions (SSLv2, SSLv3, TLSv1.0)
741
- **Certificate validation**: Always validate server certificates in production
742
- **Cipher suite selection**: Use strong cipher suites and disable weak algorithms
743
- **Certificate management**: Implement proper certificate lifecycle management
744
745
### Thread Safety
746
- **Context isolation**: Use thread-local storage for authentication contexts
747
- **Synchronized access**: Protect shared credential storage with appropriate synchronization
748
- **Resource cleanup**: Ensure proper cleanup of security contexts in multi-threaded environments
749
750
## Configuration Properties
751
752
Common security configuration properties:
753
754
### Kerberos Configuration
755
- `ranger.security.kerberos.enabled`: Enable/disable Kerberos authentication
756
- `ranger.security.kerberos.principal`: Kerberos principal for service
757
- `ranger.security.kerberos.keytab`: Path to Kerberos keytab file
758
- `ranger.security.kerberos.name.rules`: Custom Kerberos name mapping rules
759
760
### SSL Configuration
761
- `ranger.ssl.enabled`: Enable/disable SSL
762
- `ranger.ssl.keystore.file`: Path to SSL keystore
763
- `ranger.ssl.keystore.password`: SSL keystore password
764
- `ranger.ssl.truststore.file`: Path to SSL truststore
765
- `ranger.ssl.truststore.password`: SSL truststore password
766
- `ranger.ssl.protocol`: SSL protocol version (TLSv1.2, TLSv1.3)
767
768
### Authentication Configuration
769
- `ranger.auth.type`: Authentication type (simple, kerberos, ldap)
770
- `ranger.auth.cache.ttl`: Authentication cache time-to-live
771
- `ranger.auth.retry.attempts`: Number of authentication retry attempts
772
- `ranger.auth.timeout`: Authentication timeout in milliseconds