or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcatalina-core.mdconnectors.mdembedded-tomcat.mdindex.mdlogging.mdservlet-api.mdsession-management.mdutilities.mdvalves.mdweb-resources.md

authentication.mddocs/

0

# Authentication and Security

1

2

Comprehensive authentication and authorization framework including BASIC, DIGEST, FORM, and CLIENT-CERT authenticators, realm implementations for user/role management, credential handlers for password encryption, and Jakarta Authentication (JASPIC) integration for custom authentication modules.

3

4

## Capabilities

5

6

### Realm Interface

7

8

Core authentication and authorization interface.

9

10

```java { .api }

11

public interface Realm {

12

// Container

13

Container getContainer();

14

void setContainer(Container container);

15

16

// Credential handler

17

CredentialHandler getCredentialHandler();

18

void setCredentialHandler(CredentialHandler credentialHandler);

19

20

// Authentication methods

21

Principal authenticate(String username);

22

Principal authenticate(String username, String credentials);

23

Principal authenticate(String username, String digest, String nonce, String nc,

24

String cnonce, String qop, String realm, String digestA2);

25

Principal authenticate(String username, String digest, String nonce, String nc,

26

String cnonce, String qop, String realm, String digestA2, String algorithm);

27

Principal authenticate(GSSContext gssContext, boolean storeCreds);

28

Principal authenticate(GSSName gssName, GSSCredential gssCredential);

29

Principal authenticate(X509Certificate[] certs);

30

31

// Authorization

32

boolean hasRole(Wrapper wrapper, Principal principal, String role);

33

boolean hasResourcePermission(Request request, Response response,

34

SecurityConstraint[] constraints, Context context) throws IOException;

35

boolean hasUserDataPermission(Request request, Response response,

36

SecurityConstraint[] constraints) throws IOException;

37

38

// Background processing

39

void backgroundProcess();

40

41

// Security constraints

42

SecurityConstraint[] findSecurityConstraints(Request request, Context context);

43

44

// Event listeners

45

void addPropertyChangeListener(PropertyChangeListener listener);

46

void removePropertyChangeListener(PropertyChangeListener listener);

47

}

48

```

49

50

### Realm Implementations

51

52

Tomcat provides multiple concrete realm implementations for different user storage backends.

53

54

```java { .api }

55

/**

56

* Base class for Realm implementations providing common functionality.

57

*/

58

public abstract class RealmBase implements Realm, Lifecycle {

59

protected Container container;

60

protected CredentialHandler credentialHandler;

61

62

// Subclasses must implement these methods

63

protected abstract String getPassword(String username);

64

protected abstract Principal getPrincipal(String username);

65

public abstract boolean hasRole(Wrapper wrapper, Principal principal, String role);

66

}

67

68

/**

69

* Simple in-memory realm for development and testing.

70

* Users and roles are defined in tomcat-users.xml.

71

*/

72

public class MemoryRealm extends RealmBase {

73

public MemoryRealm();

74

75

/** Set path to the users configuration file */

76

public void setPathname(String pathname);

77

public String getPathname();

78

}

79

80

/**

81

* Realm implementation that reads user information from a JDBC database.

82

*/

83

public class DataSourceRealm extends RealmBase {

84

public DataSourceRealm();

85

86

/** Set the JNDI name of the DataSource */

87

public void setDataSourceName(String dataSourceName);

88

public String getDataSourceName();

89

90

/** Set the SQL query to retrieve user credentials */

91

public void setUserCredCol(String userCredCol);

92

public String getUserCredCol();

93

94

/** Set the SQL query to retrieve user roles */

95

public void setUserRoleTable(String userRoleTable);

96

public String getUserRoleTable();

97

98

/** Set the name column in user table */

99

public void setUserNameCol(String userNameCol);

100

public String getUserNameCol();

101

102

/** Set the name of the user table */

103

public void setUserTable(String userTable);

104

public String getUserTable();

105

106

/** Set the role name column */

107

public void setRoleNameCol(String roleNameCol);

108

public String getRoleNameCol();

109

}

110

111

/**

112

* Realm implementation that authenticates users against an LDAP directory.

113

*/

114

public class JNDIRealm extends RealmBase {

115

public JNDIRealm();

116

117

/** Set the connection URL for the LDAP server */

118

public void setConnectionURL(String connectionURL);

119

public String getConnectionURL();

120

121

/** Set the connection name (DN) to use for authentication */

122

public void setConnectionName(String connectionName);

123

public String getConnectionName();

124

125

/** Set the connection password */

126

public void setConnectionPassword(String connectionPassword);

127

128

/** Set the base DN for user searches */

129

public void setUserBase(String userBase);

130

public String getUserBase();

131

132

/** Set the search pattern for finding users */

133

public void setUserSearch(String userSearch);

134

public String getUserSearch();

135

136

/** Set the base DN for role searches */

137

public void setRoleBase(String roleBase);

138

public String getRoleBase();

139

140

/** Set the search pattern for finding roles */

141

public void setRoleSearch(String roleSearch);

142

public String getRoleSearch();

143

144

/** Set the attribute name for role names */

145

public void setRoleName(String roleName);

146

public String getRoleName();

147

148

/** Set whether to use subtree scope for searches */

149

public void setRoleSubtree(boolean roleSubtree);

150

public boolean getRoleSubtree();

151

152

/** Set whether nested groups should be searched */

153

public void setRoleNested(boolean roleNested);

154

public boolean getRoleNested();

155

}

156

157

/**

158

* Realm implementation that uses JAAS for authentication.

159

*/

160

public class JAASRealm extends RealmBase {

161

public JAASRealm();

162

163

/** Set the JAAS application name */

164

public void setAppName(String appName);

165

public String getAppName();

166

167

/** Set the user class name */

168

public void setUserClassNames(String userClassNames);

169

public String getUserClassNames();

170

171

/** Set the role class names */

172

public void setRoleClassNames(String roleClassNames);

173

public String getRoleClassNames();

174

175

/** Set whether to use context class loader */

176

public void setUseContextClassLoader(boolean useContextClassLoader);

177

public boolean isUseContextClassLoader();

178

}

179

180

/**

181

* Realm implementation that uses the UserDatabase JNDI resource.

182

*/

183

public class UserDatabaseRealm extends RealmBase {

184

public UserDatabaseRealm();

185

186

/** Set the JNDI name of the UserDatabase resource */

187

public void setResourceName(String resourceName);

188

public String getResourceName();

189

}

190

191

/**

192

* Realm that combines multiple realms for authentication.

193

* Attempts authentication against each realm in sequence.

194

*/

195

public class CombinedRealm extends RealmBase {

196

public CombinedRealm();

197

198

/** Add a realm to the combined realm */

199

public void addRealm(Realm realm);

200

201

/** Get all configured realms */

202

public Realm[] getNestedRealms();

203

}

204

205

/**

206

* Realm that provides brute force attack protection by locking out users

207

* after too many failed authentication attempts.

208

*/

209

public class LockOutRealm extends CombinedRealm {

210

public LockOutRealm();

211

212

/** Set the number of failed attempts before lockout */

213

public void setFailureCount(int failureCount);

214

public int getFailureCount();

215

216

/** Set the lockout duration in seconds */

217

public void setLockOutTime(int lockOutTime);

218

public int getLockOutTime();

219

220

/** Set the time window for counting failures in seconds */

221

public void setCacheSize(int cacheSize);

222

public int getCacheSize();

223

224

/** Set whether to cache authenticated users */

225

public void setCacheRemovalWarningTime(int cacheRemovalWarningTime);

226

public int getCacheRemovalWarningTime();

227

}

228

229

/**

230

* No-op realm that always denies authentication.

231

* Useful for applications that don't require authentication.

232

*/

233

public class NullRealm extends RealmBase {

234

public NullRealm();

235

}

236

```

237

238

### Credential Handler

239

240

Credential handler implementations for password encryption and verification.

241

242

```java { .api }

243

/**

244

* Base credential handler interface.

245

*/

246

public interface CredentialHandler {

247

boolean matches(String inputCredentials, String storedCredentials);

248

String mutate(String inputCredentials);

249

}

250

251

/**

252

* Credential handler using message digest algorithms (MD5, SHA-256, etc.).

253

*/

254

public class MessageDigestCredentialHandler implements CredentialHandler {

255

public MessageDigestCredentialHandler();

256

257

/** Set the digest algorithm (e.g., "SHA-256", "MD5") */

258

public void setAlgorithm(String algorithm);

259

public String getAlgorithm();

260

261

/** Set the digest encoding ("hex" or "base64") */

262

public void setEncoding(String encoding);

263

public String getEncoding();

264

265

/** Set the number of iterations for key derivation */

266

public void setIterations(int iterations);

267

public int getIterations();

268

269

/** Set the salt length in bytes */

270

public void setSaltLength(int saltLength);

271

public int getSaltLength();

272

273

@Override

274

public boolean matches(String inputCredentials, String storedCredentials);

275

276

@Override

277

public String mutate(String inputCredentials);

278

}

279

280

/**

281

* Credential handler using SecretKeyFactory for PBKDF2 and similar algorithms.

282

*/

283

public class SecretKeyCredentialHandler implements CredentialHandler {

284

public SecretKeyCredentialHandler();

285

286

/** Set the algorithm (e.g., "PBKDF2WithHmacSHA256") */

287

public void setAlgorithm(String algorithm);

288

public String getAlgorithm();

289

290

/** Set the number of iterations */

291

public void setIterations(int iterations);

292

public int getIterations();

293

294

/** Set the key length in bits */

295

public void setKeyLength(int keyLength);

296

public int getKeyLength();

297

298

/** Set the salt length in bytes */

299

public void setSaltLength(int saltLength);

300

public int getSaltLength();

301

302

@Override

303

public boolean matches(String inputCredentials, String storedCredentials);

304

305

@Override

306

public String mutate(String inputCredentials);

307

}

308

309

/**

310

* Credential handler that supports multiple nested credential handlers.

311

* Tries each handler in sequence for matching.

312

*/

313

public class NestedCredentialHandler implements CredentialHandler {

314

public NestedCredentialHandler();

315

316

/** Add a credential handler */

317

public void addCredentialHandler(CredentialHandler handler);

318

319

/** Get all configured credential handlers */

320

public CredentialHandler[] getCredentialHandlers();

321

322

@Override

323

public boolean matches(String inputCredentials, String storedCredentials);

324

325

@Override

326

public String mutate(String inputCredentials);

327

}

328

```

329

330

**Configuration Example:**

331

332

```java

333

import org.apache.catalina.realm.DataSourceRealm;

334

import org.apache.catalina.realm.MessageDigestCredentialHandler;

335

336

// Configure DataSource realm with SHA-256 password hashing

337

DataSourceRealm realm = new DataSourceRealm();

338

realm.setDataSourceName("java:comp/env/jdbc/UserDB");

339

realm.setUserTable("users");

340

realm.setUserNameCol("username");

341

realm.setUserCredCol("password");

342

realm.setUserRoleTable("user_roles");

343

realm.setRoleNameCol("role_name");

344

345

// Configure credential handler

346

MessageDigestCredentialHandler credentialHandler = new MessageDigestCredentialHandler();

347

credentialHandler.setAlgorithm("SHA-256");

348

credentialHandler.setIterations(100000);

349

credentialHandler.setSaltLength(32);

350

realm.setCredentialHandler(credentialHandler);

351

352

// Attach to context

353

context.setRealm(realm);

354

```

355

356

### Authenticator Interface

357

358

Valve that performs authentication.

359

360

```java { .api }

361

public interface Authenticator {

362

boolean authenticate(Request request, HttpServletResponse response) throws IOException;

363

void login(String userName, String password, Request request) throws ServletException;

364

void logout(Request request);

365

}

366

```

367

368

### Security Constraint

369

370

Configuration for URL-based security constraints.

371

372

```java { .api }

373

public class SecurityConstraint implements Serializable {

374

// Constructor

375

public SecurityConstraint();

376

377

// Display name

378

public void setDisplayName(String displayName);

379

public String getDisplayName();

380

381

// Auth constraint

382

public void setAuthConstraint(boolean authConstraint);

383

public boolean getAuthConstraint();

384

public void addAuthRole(String authRole);

385

public boolean findAuthRole(String role);

386

public String[] findAuthRoles();

387

public void removeAuthRole(String authRole);

388

389

// User data constraint

390

public void setUserConstraint(String userConstraint);

391

public String getUserConstraint();

392

393

// Collections

394

public void addCollection(SecurityCollection collection);

395

public SecurityCollection[] findCollections();

396

public void removeCollection(SecurityCollection collection);

397

}

398

399

public class SecurityCollection implements Serializable {

400

// Constructor

401

public SecurityCollection();

402

public SecurityCollection(String name);

403

404

// Name and description

405

public void setName(String name);

406

public String getName();

407

public void setDescription(String description);

408

public String getDescription();

409

410

// URL patterns

411

public void addPattern(String pattern);

412

public boolean findPattern(String pattern);

413

public String[] findPatterns();

414

public void removePattern(String pattern);

415

416

// HTTP methods

417

public void addMethod(String method);

418

public boolean findMethod(String method);

419

public String[] findMethods();

420

public void removeMethod(String method);

421

422

// Omitted HTTP methods

423

public void addOmittedMethod(String method);

424

public boolean findOmittedMethod(String method);

425

public String[] findOmittedMethods();

426

public void removeOmittedMethod(String method);

427

}

428

429

public class LoginConfig implements Serializable {

430

// Constructor

431

public LoginConfig();

432

433

// Authentication method

434

public void setAuthMethod(String authMethod);

435

public String getAuthMethod();

436

437

// Realm name

438

public void setRealmName(String realmName);

439

public String getRealmName();

440

441

// Login and error pages (for FORM authentication)

442

public void setLoginPage(String loginPage);

443

public String getLoginPage();

444

public void setErrorPage(String errorPage);

445

public String getErrorPage();

446

}

447

```

448

449

### JASPIC Support

450

451

Jakarta Authentication (JASPIC) interfaces.

452

453

```java { .api }

454

// Server authentication module

455

public interface ServerAuthModule {

456

void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy,

457

CallbackHandler handler, Map<String,Object> options) throws AuthException;

458

AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject,

459

Subject serviceSubject) throws AuthException;

460

AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject)

461

throws AuthException;

462

void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException;

463

Class<?>[] getSupportedMessageTypes();

464

}

465

466

// Authentication status

467

public class AuthStatus {

468

public static final AuthStatus SUCCESS;

469

public static final AuthStatus FAILURE;

470

public static final AuthStatus SEND_SUCCESS;

471

public static final AuthStatus SEND_FAILURE;

472

public static final AuthStatus SEND_CONTINUE;

473

}

474

475

// Message info

476

public interface MessageInfo {

477

Object getRequestMessage();

478

Object getResponseMessage();

479

void setRequestMessage(Object request);

480

void setResponseMessage(Object response);

481

Map<String,Object> getMap();

482

}

483

```

484

485

## Usage Examples

486

487

### Basic Authentication Configuration

488

489

```java

490

import org.apache.catalina.startup.Tomcat;

491

import org.apache.catalina.Context;

492

import org.apache.tomcat.util.descriptor.web.SecurityConstraint;

493

import org.apache.tomcat.util.descriptor.web.SecurityCollection;

494

import org.apache.tomcat.util.descriptor.web.LoginConfig;

495

496

public class BasicAuthExample {

497

public static void main(String[] args) throws Exception {

498

Tomcat tomcat = new Tomcat();

499

tomcat.setPort(8080);

500

501

Context ctx = tomcat.addWebapp("/secure", "/path/to/webapp");

502

503

// Add users

504

tomcat.addUser("admin", "admin123");

505

tomcat.addRole("admin", "manager");

506

507

// Add security constraint

508

SecurityConstraint constraint = new SecurityConstraint();

509

constraint.setAuthConstraint(true);

510

constraint.addAuthRole("manager");

511

512

SecurityCollection collection = new SecurityCollection();

513

collection.addPattern("/admin/*");

514

constraint.addCollection(collection);

515

516

ctx.addConstraint(constraint);

517

518

// Configure login

519

LoginConfig config = new LoginConfig();

520

config.setAuthMethod("BASIC");

521

config.setRealmName("Protected Area");

522

ctx.setLoginConfig(config);

523

524

tomcat.start();

525

tomcat.getServer().await();

526

}

527

}

528

```

529