or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdindex.mdjaas.mdlogin-services.mdsecurity-framework.mduser-identity.md

jaas.mddocs/

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.