0
# JAAS Integration
1
2
Java Authentication and Authorization Service (JAAS) integration provides enterprise-grade authentication with pluggable login modules and standardized security contexts.
3
4
## Core JAAS Components
5
6
### JAASLoginService
7
8
Main login service for JAAS integration:
9
10
```java { .api }
11
public class JAASLoginService extends AbstractLoginService {
12
13
// Default role class name
14
public static final String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.security.jaas.JAASRole";
15
16
// Thread-local instance access
17
public static final ThreadLocal<JAASLoginService> INSTANCE = new ThreadLocal<>();
18
19
// Constructors
20
public JAASLoginService();
21
public JAASLoginService(String name);
22
23
// Configuration
24
public String getName();
25
public void setName(String name);
26
27
public Configuration getConfiguration();
28
public void setConfiguration(Configuration configuration);
29
30
// Login module configuration
31
public void setLoginModuleName(String name);
32
public String getLoginModuleName();
33
34
// Callback handler configuration
35
public void setCallbackHandlerClass(String classname);
36
public String getCallbackHandlerClass();
37
38
// Role class configuration
39
public void setRoleClassNames(String[] classnames);
40
public String[] getRoleClassNames();
41
42
@Override
43
protected UserPrincipal loadUserInfo(String username);
44
45
@Override
46
protected List<RolePrincipal> loadRoleInfo(UserPrincipal user);
47
}
48
```
49
50
### JAASUserPrincipal
51
52
Principal for JAAS-authenticated users:
53
54
```java { .api }
55
public class JAASUserPrincipal extends UserPrincipal {
56
57
// Constructor
58
public JAASUserPrincipal(String name, Subject subject, LoginContext loginContext);
59
60
// JAAS-specific access
61
public LoginContext getLoginContext();
62
public Subject getSubject();
63
64
@Override
65
public void configureSubject(Subject subject);
66
67
@Override
68
public void deconfigureSubject(Subject subject);
69
}
70
```
71
72
## JAAS Principals and Roles
73
74
### JAASRole
75
76
Principal representing a role in JAAS authentication:
77
78
```java { .api }
79
public class JAASRole extends JAASPrincipal {
80
81
public JAASRole(String roleName);
82
83
@Override
84
public String getName();
85
86
@Override
87
public boolean equals(Object other);
88
89
@Override
90
public int hashCode();
91
}
92
```
93
94
### JAASPrincipal
95
96
Base class for JAAS principals:
97
98
```java { .api }
99
public abstract class JAASPrincipal implements Principal, Serializable {
100
101
protected JAASPrincipal(String name);
102
103
@Override
104
public abstract String getName();
105
106
@Override
107
public boolean equals(Object other);
108
109
@Override
110
public int hashCode();
111
112
@Override
113
public String toString();
114
}
115
```
116
117
## JAAS Callback Handlers
118
119
### AbstractCallbackHandler
120
121
Base class for JAAS callback handlers:
122
123
```java { .api }
124
public abstract class AbstractCallbackHandler implements CallbackHandler {
125
126
// Protected fields for subclasses
127
protected String _userName;
128
protected Object _credential;
129
protected Request _request;
130
131
// Accessor methods
132
public void setUserName(String userName);
133
public void setCredential(Object credential);
134
public void setRequest(Request request);
135
136
@Override
137
public abstract void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException;
138
}
139
```
140
141
### DefaultCallbackHandler
142
143
Default implementation supporting common callback types:
144
145
```java { .api }
146
public class DefaultCallbackHandler extends AbstractCallbackHandler {
147
148
// Configuration
149
public void setRequest(Request request);
150
public void setCredential(Object credential);
151
public void setUserName(String userName);
152
153
@Override
154
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
155
156
for (Callback callback : callbacks) {
157
158
if (callback instanceof NameCallback) {
159
NameCallback nameCallback = (NameCallback) callback;
160
nameCallback.setName(_userName);
161
162
} else if (callback instanceof PasswordCallback) {
163
PasswordCallback passwordCallback = (PasswordCallback) callback;
164
if (_credential instanceof String) {
165
passwordCallback.setPassword(((String) _credential).toCharArray());
166
}
167
168
} else if (callback instanceof ObjectCallback) {
169
ObjectCallback objectCallback = (ObjectCallback) callback;
170
objectCallback.setObject(_credential);
171
172
} else if (callback instanceof RequestCallback) {
173
RequestCallback requestCallback = (RequestCallback) callback;
174
requestCallback.setRequest(_request);
175
176
} else if (callback instanceof RequestParameterCallback) {
177
RequestParameterCallback paramCallback = (RequestParameterCallback) callback;
178
paramCallback.setParameterValues(_request.getParameters().getValues(paramCallback.getParameterName()));
179
180
} else {
181
throw new UnsupportedCallbackException(callback);
182
}
183
}
184
}
185
}
186
```
187
188
### Custom Callback Types
189
190
```java { .api }
191
// ObjectCallback - for retrieving arbitrary objects
192
public class ObjectCallback implements Callback {
193
194
public ObjectCallback();
195
196
public void setObject(Object obj);
197
public Object getObject();
198
199
public void clearObject();
200
}
201
202
// RequestCallback - for retrieving the current HTTP request
203
public class RequestCallback implements Callback {
204
205
public RequestCallback();
206
207
public void setRequest(Request request);
208
public Request getRequest();
209
}
210
211
// RequestParameterCallback - for retrieving request parameters
212
public class RequestParameterCallback implements Callback {
213
214
public RequestParameterCallback(String parameterName);
215
216
public String getParameterName();
217
public void setParameterValues(List<String> parameterValues);
218
public List<String> getParameterValues();
219
}
220
```
221
222
## JAAS Login Modules
223
224
### AbstractLoginModule
225
226
Base class for JAAS login modules:
227
228
```java { .api }
229
public abstract class AbstractLoginModule implements LoginModule {
230
231
// JAAS lifecycle
232
@Override
233
public boolean initialize(Subject subject, CallbackHandler callbackHandler,
234
Map<String, ?> sharedState, Map<String, ?> options);
235
236
@Override
237
public boolean login() throws LoginException;
238
239
@Override
240
public boolean commit() throws LoginException;
241
242
@Override
243
public boolean abort() throws LoginException;
244
245
@Override
246
public boolean logout() throws LoginException;
247
248
// Protected utility methods for subclasses
249
protected Set<JAASRole> getRoles() throws IOException, UnsupportedCallbackException;
250
protected UserPrincipal getUserPrincipal(String username) throws IOException, UnsupportedCallbackException;
251
}
252
```
253
254
### AbstractDatabaseLoginModule
255
256
Base for database-backed login modules:
257
258
```java { .api }
259
public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule {
260
261
// Database connection management
262
protected String dbDriver;
263
protected String dbUrl;
264
protected String dbUserName;
265
protected String dbPassword;
266
267
// Connection lifecycle
268
protected Connection getConnection() throws SQLException;
269
protected void closeConnection(Connection connection);
270
271
// Abstract methods for subclasses
272
protected abstract UserInfo getUserInfo(String username) throws SQLException;
273
protected abstract List<String> getUserRoles(String username) throws SQLException;
274
}
275
```
276
277
### JDBCLoginModule
278
279
JAAS login module for JDBC database authentication:
280
281
```java { .api }
282
public class JDBCLoginModule extends AbstractDatabaseLoginModule {
283
284
// Configuration options (set in JAAS config file)
285
// - dbDriver: JDBC driver class name
286
// - dbUrl: Database URL
287
// - dbUserName: Database username
288
// - dbPassword: Database password
289
// - userTable: User table name
290
// - userField: Username column name
291
// - credentialField: Password column name
292
// - roleTable: Role table name
293
// - roleField: Role name column name
294
// - userRoleTable: User-role mapping table name
295
296
@Override
297
public boolean login() throws LoginException {
298
299
try {
300
// Get credentials from callback handler
301
Callback[] callbacks = new Callback[] {
302
new NameCallback("Username: "),
303
new PasswordCallback("Password: ", false)
304
};
305
306
callbackHandler.handle(callbacks);
307
308
String username = ((NameCallback) callbacks[0]).getName();
309
char[] password = ((PasswordCallback) callbacks[1]).getPassword();
310
311
// Authenticate against database
312
if (authenticateUser(username, password)) {
313
// Load user and roles
314
currentUser = loadUserPrincipal(username);
315
currentRoles = loadUserRoles(username);
316
return true;
317
}
318
319
return false;
320
321
} catch (Exception e) {
322
throw new LoginException("JDBC authentication failed: " + e.getMessage());
323
}
324
}
325
326
@Override
327
protected UserInfo getUserInfo(String username) throws SQLException;
328
329
@Override
330
protected List<String> getUserRoles(String username) throws SQLException;
331
332
private boolean authenticateUser(String username, char[] password) throws SQLException;
333
private UserPrincipal loadUserPrincipal(String username) throws SQLException;
334
private Set<JAASRole> loadUserRoles(String username) throws SQLException;
335
}
336
```
337
338
### DataSourceLoginModule
339
340
JAAS login module using DataSource:
341
342
```java { .api }
343
public class DataSourceLoginModule extends AbstractDatabaseLoginModule {
344
345
// Configuration options:
346
// - dataSourceName: JNDI name of DataSource
347
// - userTable, userField, credentialField: User table configuration
348
// - roleTable, roleField, userRoleTable: Role table configuration
349
350
@Override
351
protected Connection getConnection() throws SQLException {
352
// Use JNDI DataSource instead of direct connection
353
InitialContext ctx = new InitialContext();
354
DataSource ds = (DataSource) ctx.lookup(dataSourceName);
355
return ds.getConnection();
356
}
357
358
@Override
359
protected UserInfo getUserInfo(String username) throws SQLException;
360
361
@Override
362
protected List<String> getUserRoles(String username) throws SQLException;
363
}
364
```
365
366
### LdapLoginModule
367
368
JAAS login module for LDAP authentication:
369
370
```java { .api }
371
public class LdapLoginModule extends AbstractLoginModule {
372
373
// LDAP configuration options:
374
// - hostname: LDAP server hostname
375
// - port: LDAP server port
376
// - contextFactory: LDAP context factory class
377
// - bindDn: Bind DN for LDAP connection
378
// - bindPassword: Bind password
379
// - userBaseDn: Base DN for user searches
380
// - roleBaseDn: Base DN for role searches
381
// - userIdAttribute: User ID attribute name
382
// - userPasswordAttribute: Password attribute name
383
// - userObjectClass: User object class
384
// - roleIdAttribute: Role ID attribute name
385
// - roleMemberAttribute: Role membership attribute
386
// - roleObjectClass: Role object class
387
388
@Override
389
public boolean login() throws LoginException {
390
391
try {
392
// Get credentials from callback handler
393
Callback[] callbacks = new Callback[] {
394
new NameCallback("Username: "),
395
new PasswordCallback("Password: ", false)
396
};
397
398
callbackHandler.handle(callbacks);
399
400
String username = ((NameCallback) callbacks[0]).getName();
401
char[] password = ((PasswordCallback) callbacks[1]).getPassword();
402
403
// Authenticate against LDAP
404
if (authenticateWithLDAP(username, password)) {
405
currentUser = createUserPrincipal(username);
406
currentRoles = loadLDAPRoles(username);
407
return true;
408
}
409
410
return false;
411
412
} catch (Exception e) {
413
throw new LoginException("LDAP authentication failed: " + e.getMessage());
414
}
415
}
416
417
private boolean authenticateWithLDAP(String username, char[] password) throws Exception;
418
private UserPrincipal createUserPrincipal(String username) throws Exception;
419
private Set<JAASRole> loadLDAPRoles(String username) throws Exception;
420
}
421
```
422
423
### PropertyFileLoginModule
424
425
JAAS login module for property file authentication:
426
427
```java { .api }
428
public class PropertyFileLoginModule extends AbstractLoginModule {
429
430
// Configuration options:
431
// - file: Path to properties file
432
433
@Override
434
public boolean login() throws LoginException {
435
436
try {
437
// Get credentials from callback handler
438
Callback[] callbacks = new Callback[] {
439
new NameCallback("Username: "),
440
new PasswordCallback("Password: ", false)
441
};
442
443
callbackHandler.handle(callbacks);
444
445
String username = ((NameCallback) callbacks[0]).getName();
446
char[] password = ((PasswordCallback) callbacks[1]).getPassword();
447
448
// Load properties file
449
Properties users = loadUserProperties();
450
451
// Authenticate user
452
String userEntry = users.getProperty(username);
453
if (userEntry != null && authenticateUser(userEntry, password)) {
454
currentUser = createUserPrincipal(username);
455
currentRoles = parseRoles(userEntry);
456
return true;
457
}
458
459
return false;
460
461
} catch (Exception e) {
462
throw new LoginException("Property file authentication failed: " + e.getMessage());
463
}
464
}
465
466
private Properties loadUserProperties() throws IOException;
467
private boolean authenticateUser(String userEntry, char[] password);
468
private UserPrincipal createUserPrincipal(String username);
469
private Set<JAASRole> parseRoles(String userEntry);
470
}
471
```
472
473
## JAAS Configuration
474
475
### Programmatic Configuration
476
477
```java { .api }
478
public class JAASConfigurationExample {
479
480
public void setupJAASLoginService() {
481
JAASLoginService jaasLogin = new JAASLoginService();
482
jaasLogin.setName("JAASRealm");
483
484
// Set login module name (must match JAAS config)
485
jaasLogin.setLoginModuleName("myLoginModule");
486
487
// Set callback handler
488
jaasLogin.setCallbackHandlerClass("com.example.MyCallbackHandler");
489
490
// Configure role classes
491
jaasLogin.setRoleClassNames(new String[] {
492
"org.eclipse.jetty.security.jaas.JAASRole",
493
"com.example.CustomRole"
494
});
495
496
// Use with security handler
497
SecurityHandler security = new SecurityHandler.PathMapped();
498
security.setLoginService(jaasLogin);
499
}
500
501
public void setupProgrammaticConfiguration() {
502
503
// Create JAAS configuration programmatically
504
Configuration jaasConfig = new Configuration() {
505
@Override
506
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
507
508
if ("myLoginModule".equals(name)) {
509
Map<String, String> options = new HashMap<>();
510
options.put("dbDriver", "com.mysql.cj.jdbc.Driver");
511
options.put("dbUrl", "jdbc:mysql://localhost:3306/users");
512
options.put("dbUserName", "app");
513
options.put("dbPassword", "secret");
514
options.put("userTable", "users");
515
options.put("userField", "username");
516
options.put("credentialField", "password");
517
options.put("roleTable", "roles");
518
options.put("roleField", "role_name");
519
options.put("userRoleTable", "user_roles");
520
521
AppConfigurationEntry entry = new AppConfigurationEntry(
522
"org.eclipse.jetty.security.jaas.spi.JDBCLoginModule",
523
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
524
options
525
);
526
527
return new AppConfigurationEntry[] { entry };
528
}
529
530
return null;
531
}
532
};
533
534
// Set the configuration
535
JAASLoginService jaasLogin = new JAASLoginService();
536
jaasLogin.setConfiguration(jaasConfig);
537
}
538
}
539
```
540
541
### JAAS Configuration Files
542
543
```java
544
// jaas.conf file format
545
546
// JDBC Login Module Configuration
547
myApp-JDBC {
548
org.eclipse.jetty.security.jaas.spi.JDBCLoginModule required
549
dbDriver="com.mysql.cj.jdbc.Driver"
550
dbUrl="jdbc:mysql://localhost:3306/myapp"
551
dbUserName="app_user"
552
dbPassword="app_password"
553
userTable="users"
554
userField="username"
555
credentialField="password"
556
roleTable="user_roles"
557
roleField="role"
558
userRoleTable="user_roles";
559
};
560
561
// LDAP Login Module Configuration
562
myApp-LDAP {
563
org.eclipse.jetty.security.jaas.spi.LdapLoginModule required
564
hostname="ldap.example.com"
565
port="389"
566
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
567
bindDn="cn=admin,dc=example,dc=com"
568
bindPassword="secret"
569
userBaseDn="ou=users,dc=example,dc=com"
570
roleBaseDn="ou=roles,dc=example,dc=com"
571
userIdAttribute="uid"
572
userPasswordAttribute="userPassword"
573
userObjectClass="inetOrgPerson"
574
roleIdAttribute="cn"
575
roleMemberAttribute="member"
576
roleObjectClass="groupOfNames";
577
};
578
579
// Property File Login Module Configuration
580
myApp-Properties {
581
org.eclipse.jetty.security.jaas.spi.PropertyFileLoginModule required
582
file="/etc/myapp/users.properties";
583
};
584
585
// Multi-module configuration (try LDAP first, fallback to local)
586
myApp-Multi {
587
org.eclipse.jetty.security.jaas.spi.LdapLoginModule sufficient
588
hostname="ldap.example.com"
589
port="389"
590
userBaseDn="ou=users,dc=example,dc=com";
591
592
org.eclipse.jetty.security.jaas.spi.PropertyFileLoginModule required
593
file="/etc/myapp/local-users.properties";
594
};
595
```
596
597
### System Property Configuration
598
599
```java { .api }
600
public class JAASSystemConfiguration {
601
602
public void configureJAASSystemProperties() {
603
604
// Set JAAS configuration file
605
System.setProperty("java.security.auth.login.config", "/path/to/jaas.conf");
606
607
// Enable JAAS debug logging
608
System.setProperty("java.security.debug", "logincontext,policy,scl,gssloginconfig");
609
610
// Set security manager (if required)
611
System.setProperty("java.security.manager", "");
612
System.setProperty("java.security.policy", "/path/to/security.policy");
613
614
// Kerberos configuration (for SPNEGO)
615
System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
616
System.setProperty("sun.security.krb5.debug", "true");
617
618
// Create JAAS login service
619
JAASLoginService jaasLogin = new JAASLoginService("MyRealm");
620
jaasLogin.setLoginModuleName("myApp-JDBC");
621
}
622
}
623
```
624
625
## PropertyUserStoreManager
626
627
### Managing Property User Stores
628
629
```java { .api }
630
public class PropertyUserStoreManager {
631
632
// Static store management
633
public static PropertyUserStore getPropertyUserStore(String name);
634
public static PropertyUserStore getPropertyUserStore(String name, String configPath);
635
636
// Store lifecycle
637
public static void addPropertyUserStore(String name, PropertyUserStore store);
638
public static void removePropertyUserStore(String name);
639
640
// Configuration management
641
public static void setReloadInterval(String name, int seconds);
642
public static void enableHotReload(String name, boolean enable);
643
}
644
```
645
646
## Advanced JAAS Examples
647
648
### Custom Login Module
649
650
```java { .api }
651
public class TokenLoginModule extends AbstractLoginModule {
652
653
@Override
654
public boolean initialize(Subject subject, CallbackHandler callbackHandler,
655
Map<String, ?> sharedState, Map<String, ?> options) {
656
657
super.initialize(subject, callbackHandler, sharedState, options);
658
659
// Get configuration options
660
this.tokenValidator = (String) options.get("tokenValidator");
661
this.roleAttribute = (String) options.get("roleAttribute");
662
663
return true;
664
}
665
666
@Override
667
public boolean login() throws LoginException {
668
669
try {
670
// Custom callback for token
671
Callback[] callbacks = new Callback[] {
672
new ObjectCallback() // Custom token callback
673
};
674
675
callbackHandler.handle(callbacks);
676
677
Object token = ((ObjectCallback) callbacks[0]).getObject();
678
679
if (validateToken(token)) {
680
TokenInfo tokenInfo = parseToken(token);
681
currentUser = createUserPrincipal(tokenInfo.getSubject());
682
currentRoles = createRoles(tokenInfo.getRoles());
683
return true;
684
}
685
686
return false;
687
688
} catch (Exception e) {
689
throw new LoginException("Token authentication failed: " + e.getMessage());
690
}
691
}
692
693
private boolean validateToken(Object token);
694
private TokenInfo parseToken(Object token);
695
private UserPrincipal createUserPrincipal(String subject);
696
private Set<JAASRole> createRoles(List<String> roleNames);
697
698
private static class TokenInfo {
699
public String getSubject() { return null; }
700
public List<String> getRoles() { return Collections.emptyList(); }
701
}
702
}
703
```
704
705
### Multi-Realm JAAS Configuration
706
707
```java { .api }
708
public class MultiRealmJAAS {
709
710
public void setupMultipleRealms() {
711
712
// Primary realm with LDAP
713
JAASLoginService primaryRealm = new JAASLoginService();
714
primaryRealm.setName("PrimaryRealm");
715
primaryRealm.setLoginModuleName("primary-ldap");
716
primaryRealm.setCallbackHandlerClass("com.example.LDAPCallbackHandler");
717
718
// Admin realm with local properties
719
JAASLoginService adminRealm = new JAASLoginService();
720
adminRealm.setName("AdminRealm");
721
adminRealm.setLoginModuleName("admin-properties");
722
adminRealm.setCallbackHandlerClass("com.example.PropertiesCallbackHandler");
723
724
// API realm with token authentication
725
JAASLoginService apiRealm = new JAASLoginService();
726
apiRealm.setName("APIRealm");
727
apiRealm.setLoginModuleName("api-tokens");
728
apiRealm.setCallbackHandlerClass("com.example.TokenCallbackHandler");
729
730
// Configure different security handlers for different areas
731
SecurityHandler.PathMapped webSecurity = new SecurityHandler.PathMapped();
732
webSecurity.setLoginService(primaryRealm);
733
webSecurity.put("/app/*", Constraint.ANY_USER);
734
735
SecurityHandler.PathMapped adminSecurity = new SecurityHandler.PathMapped();
736
adminSecurity.setLoginService(adminRealm);
737
adminSecurity.put("/admin/*", Constraint.from("admin"));
738
739
SecurityHandler.PathMapped apiSecurity = new SecurityHandler.PathMapped();
740
apiSecurity.setLoginService(apiRealm);
741
apiSecurity.put("/api/*", Constraint.from("api-user"));
742
}
743
}
744
```
745
746
### JAAS with Custom Callback Handler
747
748
```java { .api }
749
public class CustomJAASCallbackHandler extends AbstractCallbackHandler {
750
751
@Override
752
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
753
754
for (Callback callback : callbacks) {
755
756
if (callback instanceof NameCallback) {
757
handleNameCallback((NameCallback) callback);
758
759
} else if (callback instanceof PasswordCallback) {
760
handlePasswordCallback((PasswordCallback) callback);
761
762
} else if (callback instanceof ObjectCallback) {
763
handleObjectCallback((ObjectCallback) callback);
764
765
} else if (callback instanceof RequestCallback) {
766
handleRequestCallback((RequestCallback) callback);
767
768
} else if (callback instanceof RequestParameterCallback) {
769
handleRequestParameterCallback((RequestParameterCallback) callback);
770
771
} else if (callback instanceof ChoiceCallback) {
772
handleChoiceCallback((ChoiceCallback) callback);
773
774
} else {
775
throw new UnsupportedCallbackException(callback,
776
"Callback type not supported: " + callback.getClass().getName());
777
}
778
}
779
}
780
781
private void handleNameCallback(NameCallback callback) {
782
// Extract username from request headers, parameters, or attributes
783
String username = extractUsernameFromRequest();
784
callback.setName(username);
785
}
786
787
private void handlePasswordCallback(PasswordCallback callback) {
788
// Extract password from request or use token-based authentication
789
String password = extractPasswordFromRequest();
790
callback.setPassword(password != null ? password.toCharArray() : null);
791
}
792
793
private void handleObjectCallback(ObjectCallback callback) {
794
// Handle custom object callbacks (e.g., tokens, certificates)
795
Object credential = extractCustomCredential();
796
callback.setObject(credential);
797
}
798
799
private void handleRequestCallback(RequestCallback callback) {
800
// Provide the HTTP request to login modules
801
callback.setRequest(_request);
802
}
803
804
private void handleRequestParameterCallback(RequestParameterCallback callback) {
805
// Extract specific request parameters
806
String paramName = callback.getParameterName();
807
List<String> values = _request.getParameters().getValues(paramName);
808
callback.setParameterValues(values);
809
}
810
811
private void handleChoiceCallback(ChoiceCallback callback) {
812
// Handle multiple choice selections (e.g., authentication methods)
813
String[] choices = callback.getChoices();
814
int selectedIndex = determineChoice(choices);
815
callback.setSelectedIndex(selectedIndex);
816
}
817
818
private String extractUsernameFromRequest() {
819
// Implementation to extract username
820
return null;
821
}
822
823
private String extractPasswordFromRequest() {
824
// Implementation to extract password
825
return null;
826
}
827
828
private Object extractCustomCredential() {
829
// Implementation to extract custom credentials
830
return null;
831
}
832
833
private int determineChoice(String[] choices) {
834
// Implementation to determine choice
835
return 0;
836
}
837
}
838
```
839
840
## Security Best Practices
841
842
### JAAS Security Configuration
843
844
```java { .api }
845
public class JAASSecurityBestPractices {
846
847
public void configureSecureJAAS() {
848
849
JAASLoginService jaasLogin = new JAASLoginService();
850
jaasLogin.setName("SecureRealm");
851
852
// Use strong authentication methods
853
jaasLogin.setLoginModuleName("multi-factor-ldap");
854
855
// Custom callback handler with security validations
856
jaasLogin.setCallbackHandlerClass("com.example.SecureCallbackHandler");
857
858
// Configure multiple role classes for fine-grained access control
859
jaasLogin.setRoleClassNames(new String[] {
860
"org.eclipse.jetty.security.jaas.JAASRole",
861
"com.example.ApplicationRole",
862
"com.example.PermissionRole"
863
});
864
865
// Enable comprehensive logging
866
System.setProperty("java.security.debug", "access,logincontext,policy");
867
868
// Set up security manager
869
setupSecurityManager();
870
}
871
872
private void setupSecurityManager() {
873
// Configure security policy for JAAS
874
System.setProperty("java.security.policy", "/etc/myapp/security.policy");
875
876
// Enable security manager
877
if (System.getSecurityManager() == null) {
878
System.setSecurityManager(new SecurityManager());
879
}
880
}
881
}
882
```
883
884
JAAS integration provides enterprise-grade authentication with standardized login modules, flexible callback handling, and comprehensive security contexts for complex authentication scenarios.