or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication-filters.mdauthorization-filters.mdenvironment-config.mdfilter-chain-management.mdindex.mdjsp-tag-library.mdservlet-filters.mdsession-management.mdweb-security-management.mdweb-subjects.mdweb-utilities.md

filter-chain-management.mddocs/

0

# Filter Chain Management

1

2

Components for managing and resolving filter chains in Apache Shiro web applications. These classes handle the registration, configuration, and resolution of servlet filter chains based on URL patterns, enabling flexible and powerful security policy configuration.

3

4

## Capabilities

5

6

### Filter Chain Resolution

7

8

Core interfaces and implementations for resolving filter chains based on incoming requests and URL patterns.

9

10

```java { .api }

11

interface FilterChainResolver {

12

/**

13

* Resolves and returns the filter chain for the given request.

14

*

15

* @param request the incoming servlet request

16

* @param response the servlet response

17

* @param originalChain the original filter chain from the servlet container

18

* @return the resolved filter chain or originalChain if no specific chain found

19

*/

20

FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);

21

}

22

```

23

24

```java { .api }

25

class PathMatchingFilterChainResolver implements FilterChainResolver {

26

/**

27

* Creates a new PathMatchingFilterChainResolver.

28

*/

29

public PathMatchingFilterChainResolver();

30

31

/**

32

* Returns the FilterChainManager used to manage filter chains.

33

*

34

* @return the FilterChainManager instance

35

*/

36

public FilterChainManager getFilterChainManager();

37

38

/**

39

* Sets the FilterChainManager to use for managing filter chains.

40

*

41

* @param filterChainManager the FilterChainManager to set

42

*/

43

public void setFilterChainManager(FilterChainManager filterChainManager);

44

45

/**

46

* Resolves the filter chain by matching the request path against configured patterns.

47

*

48

* @param request the servlet request

49

* @param response the servlet response

50

* @param originalChain the original filter chain

51

* @return the matching filter chain or originalChain if no match

52

*/

53

public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);

54

55

/**

56

* Returns the request path used for pattern matching.

57

*

58

* @param request the servlet request

59

* @return the request path within the application

60

*/

61

protected String getPathWithinApplication(ServletRequest request);

62

}

63

```

64

65

### Filter Chain Management

66

67

Interfaces and implementations for managing named filter chains and their configurations.

68

69

```java { .api }

70

interface FilterChainManager extends FilterManager {

71

/**

72

* Returns all configured filter chains.

73

*

74

* @return Map of chain names to NamedFilterList instances

75

*/

76

Map<String, NamedFilterList> getFilterChains();

77

78

/**

79

* Returns whether any filter chains have been configured.

80

*

81

* @return true if chains exist

82

*/

83

boolean hasChains();

84

85

/**

86

* Returns the filter chain with the specified name.

87

*

88

* @param chainName the name of the chain to retrieve

89

* @return the NamedFilterList for the specified chain name

90

*/

91

NamedFilterList getChain(String chainName);

92

93

/**

94

* Creates a new filter chain with the specified name and configuration.

95

*

96

* @param chainName the name of the chain to create

97

* @param chainDefinition the chain configuration string

98

* @return the created NamedFilterList

99

*/

100

NamedFilterList createChain(String chainName, String chainDefinition);

101

102

/**

103

* Adds a filter to the specified chain.

104

*

105

* @param chainName the name of the chain

106

* @param filterName the name of the filter to add

107

*/

108

void addToChain(String chainName, String filterName);

109

110

/**

111

* Adds a filter to the specified chain with configuration.

112

*

113

* @param chainName the name of the chain

114

* @param filterName the name of the filter to add

115

* @param chainSpecificFilterConfig filter-specific configuration

116

*/

117

void addToChain(String chainName, String filterName, String chainSpecificFilterConfig);

118

119

/**

120

* Creates a filter chain from the given definition string.

121

*

122

* @param chainName the name of the chain

123

* @param chainDefinition comma-delimited filter names with optional configs

124

* @return the created NamedFilterList

125

*/

126

NamedFilterList createChain(String chainName, String chainDefinition);

127

}

128

```

129

130

```java { .api }

131

class DefaultFilterChainManager extends AbstractFilterChainManager {

132

/**

133

* Creates a new DefaultFilterChainManager with default filters.

134

*/

135

public DefaultFilterChainManager();

136

137

/**

138

* Creates a new DefaultFilterChainManager with the specified FilterConfig.

139

*

140

* @param filterConfig the FilterConfig for initializing filters

141

*/

142

public DefaultFilterChainManager(FilterConfig filterConfig);

143

144

/**

145

* Returns all configured filter chains.

146

*

147

* @return Map of chain names to filter chains

148

*/

149

public Map<String, NamedFilterList> getFilterChains();

150

151

/**

152

* Returns whether any filter chains exist.

153

*

154

* @return true if chains are configured

155

*/

156

public boolean hasChains();

157

158

/**

159

* Returns the filter chain with the specified name.

160

*

161

* @param chainName the chain name

162

* @return the NamedFilterList or null if not found

163

*/

164

public NamedFilterList getChain(String chainName);

165

166

/**

167

* Creates a filter chain from the definition string.

168

*

169

* @param chainName the name for the chain

170

* @param chainDefinition comma-delimited filter configuration

171

* @return the created NamedFilterList

172

*/

173

public NamedFilterList createChain(String chainName, String chainDefinition);

174

175

/**

176

* Adds a filter to the specified chain.

177

*

178

* @param chainName the chain name

179

* @param filterName the filter name to add

180

*/

181

public void addToChain(String chainName, String filterName);

182

183

/**

184

* Adds a filter to the specified chain with configuration.

185

*

186

* @param chainName the chain name

187

* @param filterName the filter name to add

188

* @param chainSpecificFilterConfig the filter configuration

189

*/

190

public void addToChain(String chainName, String filterName, String chainSpecificFilterConfig);

191

192

/**

193

* Creates default filter instances for common Shiro filters.

194

*

195

* @return Map of filter names to Filter instances

196

*/

197

protected Map<String, Filter> createDefaultFilters();

198

199

/**

200

* Adds default filters to this manager.

201

*/

202

protected void addDefaultFilters(boolean init);

203

}

204

```

205

206

### Named Filter Lists

207

208

Classes representing named collections of filters that form filter chains.

209

210

```java { .api }

211

interface NamedFilterList extends List<Filter> {

212

/**

213

* Returns the name of this filter list.

214

*

215

* @return the filter list name

216

*/

217

String getName();

218

219

/**

220

* Creates a FilterChain that executes the filters in this list.

221

*

222

* @param originalChain the original filter chain to delegate to after processing

223

* @return a FilterChain that executes this list's filters

224

*/

225

FilterChain proxy(FilterChain originalChain);

226

}

227

```

228

229

```java { .api }

230

class SimpleNamedFilterList extends ArrayList<Filter> implements NamedFilterList {

231

/**

232

* Creates a new SimpleNamedFilterList with the specified name.

233

*

234

* @param name the name for this filter list

235

*/

236

public SimpleNamedFilterList(String name);

237

238

/**

239

* Creates a new SimpleNamedFilterList with the specified name and filters.

240

*

241

* @param name the name for this filter list

242

* @param filters the initial filters for this list

243

*/

244

public SimpleNamedFilterList(String name, List<Filter> filters);

245

246

/**

247

* Returns the name of this filter list.

248

*

249

* @return the filter list name

250

*/

251

public String getName();

252

253

/**

254

* Creates a proxied FilterChain that executes this list's filters.

255

*

256

* @param originalChain the original chain to execute after this list's filters

257

* @return a FilterChain proxy for this filter list

258

*/

259

public FilterChain proxy(FilterChain originalChain);

260

}

261

```

262

263

### Default Filters Enumeration

264

265

Enumeration defining all built-in Shiro filters available for use in filter chains.

266

267

```java { .api }

268

enum DefaultFilter {

269

anon(AnonymousFilter.class),

270

authc(FormAuthenticationFilter.class),

271

authcBasic(BasicHttpAuthenticationFilter.class),

272

authcBearer(BearerHttpAuthenticationFilter.class),

273

logout(LogoutFilter.class),

274

noSessionCreation(NoSessionCreationFilter.class),

275

perms(PermissionsAuthorizationFilter.class),

276

port(PortFilter.class),

277

rest(HttpMethodPermissionFilter.class),

278

roles(RolesAuthorizationFilter.class),

279

ssl(SslFilter.class),

280

user(UserFilter.class),

281

invalidRequest(InvalidRequestFilter.class);

282

283

/**

284

* Creates a new instance of this filter.

285

*

286

* @return a new Filter instance

287

*/

288

public Filter newInstance();

289

290

/**

291

* Returns the Filter class for this default filter.

292

*

293

* @return the Filter class

294

*/

295

public Class<? extends Filter> getFilterClass();

296

297

/**

298

* Creates a map of all default filters with their names as keys.

299

*

300

* @param filterConfig the FilterConfig for filter initialization

301

* @return Map of filter names to Filter instances

302

*/

303

public static Map<String, Filter> createInstanceMap(FilterConfig filterConfig);

304

}

305

```

306

307

### Filter Management Base Classes

308

309

Abstract base classes providing common filter management functionality.

310

311

```java { .api }

312

abstract class AbstractFilterChainManager implements FilterChainManager {

313

/**

314

* Returns all registered filters.

315

*

316

* @return Map of filter names to Filter instances

317

*/

318

public Map<String, Filter> getFilters();

319

320

/**

321

* Returns the filter with the specified name.

322

*

323

* @param name the filter name

324

* @return the Filter instance or null if not found

325

*/

326

public Filter getFilter(String name);

327

328

/**

329

* Adds a filter with the specified name.

330

*

331

* @param name the filter name

332

* @param filter the Filter instance

333

*/

334

public void addFilter(String name, Filter filter);

335

336

/**

337

* Adds a filter with the specified name and initializes it.

338

*

339

* @param name the filter name

340

* @param filter the Filter instance

341

* @param init whether to initialize the filter

342

*/

343

public void addFilter(String name, Filter filter, boolean init);

344

345

/**

346

* Creates a filter instance from the class name.

347

*

348

* @param className the fully qualified filter class name

349

* @param args constructor arguments

350

* @return the created Filter instance

351

*/

352

public Filter createFilter(String className, Object... args);

353

354

/**

355

* Initializes the specified filter.

356

*

357

* @param filter the filter to initialize

358

*/

359

protected void initFilter(Filter filter);

360

}

361

```

362

363

## Usage Examples

364

365

### Basic Filter Chain Configuration

366

367

```java

368

public void setupBasicFilterChains() {

369

// Create filter chain manager

370

DefaultFilterChainManager manager = new DefaultFilterChainManager();

371

372

// Basic authentication and authorization chains

373

manager.createChain("/login", "authc");

374

manager.createChain("/logout", "logout");

375

manager.createChain("/admin/**", "authc, roles[admin]");

376

manager.createChain("/user/**", "authc");

377

manager.createChain("/api/**", "authcBasic");

378

manager.createChain("/**", "anon");

379

380

// Create resolver and set in filter

381

PathMatchingFilterChainResolver resolver = new PathMatchingFilterChainResolver();

382

resolver.setFilterChainManager(manager);

383

384

// Use with AbstractShiroFilter

385

AbstractShiroFilter shiroFilter = new ShiroFilter();

386

shiroFilter.setFilterChainResolver(resolver);

387

}

388

```

389

390

### Advanced Filter Chain Configuration

391

392

```java

393

public void setupAdvancedFilterChains() {

394

DefaultFilterChainManager manager = new DefaultFilterChainManager();

395

396

// Add custom filters

397

manager.addFilter("jwt", new JwtAuthenticationFilter());

398

manager.addFilter("cors", new CorsFilter());

399

manager.addFilter("rate", new RateLimitFilter());

400

401

// Complex filter chains with multiple filters and configurations

402

manager.createChain("/api/public/**", "cors, anon");

403

manager.createChain("/api/auth/**", "cors, authc");

404

manager.createChain("/api/admin/**", "cors, jwt, roles[admin], rate");

405

manager.createChain("/api/users/**", "cors, jwt, perms[user:read], rate");

406

407

// SSL requirements for sensitive areas

408

manager.createChain("/secure/**", "ssl, authc, roles[user]");

409

manager.createChain("/admin/**", "ssl, authc, roles[admin]");

410

411

// Different authentication methods for different areas

412

manager.createChain("/web/login", "authc"); // Form auth for web

413

manager.createChain("/web/**", "authc, user"); // Web interface

414

manager.createChain("/api/v1/**", "authcBasic"); // Basic auth for API v1

415

manager.createChain("/api/v2/**", "jwt"); // JWT for API v2

416

417

// Create resolver

418

PathMatchingFilterChainResolver resolver = new PathMatchingFilterChainResolver();

419

resolver.setFilterChainManager(manager);

420

}

421

```

422

423

### Programmatic Chain Building

424

425

```java

426

public class FilterChainBuilder {

427

private DefaultFilterChainManager manager;

428

429

public FilterChainBuilder() {

430

this.manager = new DefaultFilterChainManager();

431

}

432

433

public FilterChainBuilder addCustomFilter(String name, Filter filter) {

434

manager.addFilter(name, filter);

435

return this;

436

}

437

438

public FilterChainBuilder publicAccess(String pattern) {

439

manager.createChain(pattern, "anon");

440

return this;

441

}

442

443

public FilterChainBuilder requireAuthentication(String pattern) {

444

manager.createChain(pattern, "authc");

445

return this;

446

}

447

448

public FilterChainBuilder requireRole(String pattern, String role) {

449

manager.createChain(pattern, "authc, roles[" + role + "]");

450

return this;

451

}

452

453

public FilterChainBuilder requirePermission(String pattern, String permission) {

454

manager.createChain(pattern, "authc, perms[" + permission + "]");

455

return this;

456

}

457

458

public FilterChainBuilder requireSsl(String pattern) {

459

manager.createChain(pattern, "ssl, authc");

460

return this;

461

}

462

463

public FilterChainBuilder apiAccess(String pattern, String authType) {

464

String chain = "cors";

465

if ("basic".equals(authType)) {

466

chain += ", authcBasic";

467

} else if ("bearer".equals(authType)) {

468

chain += ", authcBearer";

469

}

470

manager.createChain(pattern, chain);

471

return this;

472

}

473

474

public FilterChainManager build() {

475

return manager;

476

}

477

}

478

479

// Usage

480

public void buildFilterChains() {

481

FilterChainBuilder builder = new FilterChainBuilder()

482

.addCustomFilter("audit", new AuditFilter())

483

.publicAccess("/css/**")

484

.publicAccess("/js/**")

485

.publicAccess("/images/**")

486

.requireAuthentication("/login")

487

.requireSsl("/admin/**")

488

.requireRole("/admin/**", "admin")

489

.requirePermission("/reports/**", "report:read")

490

.apiAccess("/api/v1/**", "basic")

491

.apiAccess("/api/v2/**", "bearer")

492

.publicAccess("/**");

493

494

FilterChainManager manager = builder.build();

495

}

496

```

497

498

### Dynamic Filter Chain Modification

499

500

```java

501

public class DynamicFilterChainManager {

502

private DefaultFilterChainManager manager;

503

504

public DynamicFilterChainManager() {

505

this.manager = new DefaultFilterChainManager();

506

}

507

508

public void addSecurityRule(String pattern, String[] roles, String[] permissions) {

509

StringBuilder chainDef = new StringBuilder("authc");

510

511

if (roles != null && roles.length > 0) {

512

chainDef.append(", roles[").append(String.join(",", roles)).append("]");

513

}

514

515

if (permissions != null && permissions.length > 0) {

516

chainDef.append(", perms[").append(String.join(",", permissions)).append("]");

517

}

518

519

manager.createChain(pattern, chainDef.toString());

520

}

521

522

public void removeSecurityRule(String pattern) {

523

Map<String, NamedFilterList> chains = manager.getFilterChains();

524

chains.remove(pattern);

525

}

526

527

public void updateSecurityRule(String pattern, String newChainDefinition) {

528

removeSecurityRule(pattern);

529

manager.createChain(pattern, newChainDefinition);

530

}

531

532

public void addMaintenanceMode() {

533

// Add maintenance filter to all paths except admin

534

manager.addFilter("maintenance", new MaintenanceFilter());

535

manager.createChain("/**", "maintenance, anon");

536

manager.createChain("/admin/**", "ssl, authc, roles[admin]");

537

}

538

539

public void removeMaintenance() {

540

// Remove maintenance mode and restore normal chains

541

Map<String, NamedFilterList> chains = manager.getFilterChains();

542

chains.clear();

543

setupNormalChains();

544

}

545

546

private void setupNormalChains() {

547

manager.createChain("/admin/**", "ssl, authc, roles[admin]");

548

manager.createChain("/user/**", "authc");

549

manager.createChain("/**", "anon");

550

}

551

}

552

```

553

554

### Filter Chain Testing and Debugging

555

556

```java

557

public class FilterChainDebugger {

558

559

public void debugFilterChains(FilterChainManager manager) {

560

Map<String, NamedFilterList> chains = manager.getFilterChains();

561

562

System.out.println("=== Filter Chain Configuration ===");

563

for (Map.Entry<String, NamedFilterList> entry : chains.entrySet()) {

564

String pattern = entry.getKey();

565

NamedFilterList filterList = entry.getValue();

566

567

System.out.printf("Pattern: %s%n", pattern);

568

System.out.printf(" Chain: %s%n", filterList.getName());

569

System.out.printf(" Filters: ");

570

571

for (Filter filter : filterList) {

572

System.out.printf("%s ", filter.getClass().getSimpleName());

573

}

574

System.out.println();

575

}

576

}

577

578

public boolean testPathMatching(String testPath, FilterChainManager manager) {

579

PathMatchingFilterChainResolver resolver = new PathMatchingFilterChainResolver();

580

resolver.setFilterChainManager(manager);

581

582

MockHttpServletRequest request = new MockHttpServletRequest();

583

request.setRequestURI(testPath);

584

MockHttpServletResponse response = new MockHttpServletResponse();

585

586

FilterChain chain = resolver.getChain(request, response, null);

587

588

boolean hasCustomChain = !(chain instanceof javax.servlet.FilterChain);

589

System.out.printf("Path '%s' -> %s%n", testPath,

590

hasCustomChain ? "Custom Chain" : "Default Chain");

591

592

return hasCustomChain;

593

}

594

}

595

```