0
# Authentication Filters
1
2
Specialized servlet filters for various authentication mechanisms in Apache Shiro web applications. These filters handle different authentication protocols including form-based login, HTTP Basic/Bearer authentication, anonymous access, and logout processing while integrating seamlessly with Shiro's security framework.
3
4
## Capabilities
5
6
### Base Authentication Filters
7
8
Foundation classes providing common authentication functionality and templates for implementing custom authentication mechanisms.
9
10
```java { .api }
11
abstract class AuthenticationFilter extends AccessControlFilter {
12
/** Default login URL */
13
public static final String DEFAULT_LOGIN_URL = "/login";
14
15
/** Default URL to redirect to after successful login */
16
public static final String DEFAULT_SUCCESS_URL = "/";
17
18
/**
19
* Returns the URL to redirect to after successful authentication.
20
*
21
* @return the success URL
22
*/
23
public String getSuccessUrl();
24
25
/**
26
* Sets the URL to redirect to after successful authentication.
27
*
28
* @param successUrl the success URL to set
29
*/
30
public void setSuccessUrl(String successUrl);
31
32
/**
33
* Template method determining if access is allowed without authentication.
34
*
35
* @param request the servlet request
36
* @param response the servlet response
37
* @param mappedValue the configuration for this path
38
* @return true if access is allowed
39
*/
40
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue);
41
42
/**
43
* Determines if the current request is a login request.
44
*
45
* @param request the servlet request
46
* @param response the servlet response
47
* @return true if this is a login request
48
*/
49
protected boolean isLoginRequest(ServletRequest request, ServletResponse response);
50
51
/**
52
* Determines if a login attempt should be made for this request.
53
*
54
* @param request the servlet request
55
* @param response the servlet response
56
* @return true if login should be attempted
57
*/
58
protected boolean isLoginSubmission(ServletRequest request, ServletResponse response);
59
}
60
```
61
62
```java { .api }
63
abstract class AuthenticatingFilter extends AuthenticationFilter {
64
/** Default username parameter name */
65
public static final String DEFAULT_USERNAME_PARAM = "username";
66
67
/** Default password parameter name */
68
public static final String DEFAULT_PASSWORD_PARAM = "password";
69
70
/** Default remember me parameter name */
71
public static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";
72
73
/**
74
* Handles access denied scenarios by attempting authentication.
75
*
76
* @param request the servlet request
77
* @param response the servlet response
78
* @return true if authentication succeeded or was handled
79
* @throws Exception if authentication processing fails
80
*/
81
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
82
83
/**
84
* Executes the authentication attempt.
85
*
86
* @param request the servlet request
87
* @param response the servlet response
88
* @return true if authentication succeeded
89
* @throws Exception if authentication fails
90
*/
91
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception;
92
93
/**
94
* Creates an authentication token from the request.
95
*
96
* @param request the servlet request
97
* @param response the servlet response
98
* @return the authentication token
99
*/
100
protected abstract AuthenticationToken createToken(ServletRequest request, ServletResponse response);
101
102
/**
103
* Handles successful authentication.
104
*
105
* @param token the authentication token
106
* @param subject the authenticated subject
107
* @param request the servlet request
108
* @param response the servlet response
109
* @return true to continue processing
110
* @throws Exception if success handling fails
111
*/
112
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
113
ServletRequest request, ServletResponse response) throws Exception;
114
115
/**
116
* Handles failed authentication.
117
*
118
* @param token the authentication token that failed
119
* @param ae the authentication exception
120
* @param request the servlet request
121
* @param response the servlet response
122
* @return true if failure was handled and processing should continue
123
*/
124
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae,
125
ServletRequest request, ServletResponse response);
126
127
/**
128
* Redirects to the success URL after successful authentication.
129
*
130
* @param request the servlet request
131
* @param response the servlet response
132
* @throws IOException if redirect fails
133
*/
134
protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws IOException;
135
}
136
```
137
138
### Form-Based Authentication
139
140
Filter for handling HTML form-based authentication with username/password credentials and remember-me functionality.
141
142
```java { .api }
143
class FormAuthenticationFilter extends AuthenticatingFilter {
144
/** Default username parameter name */
145
public static final String DEFAULT_USERNAME_PARAM = "username";
146
147
/** Default password parameter name */
148
public static final String DEFAULT_PASSWORD_PARAM = "password";
149
150
/** Default remember me parameter name */
151
public static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";
152
153
/** Default error attribute name */
154
public static final String DEFAULT_ERROR_KEY_ATTRIBUTE_NAME = "shiroLoginFailure";
155
156
/**
157
* Creates a new FormAuthenticationFilter.
158
*/
159
public FormAuthenticationFilter();
160
161
/**
162
* Returns the username parameter name.
163
*
164
* @return the username parameter name
165
*/
166
public String getUsernameParam();
167
168
/**
169
* Sets the username parameter name.
170
*
171
* @param usernameParam the username parameter name to set
172
*/
173
public void setUsernameParam(String usernameParam);
174
175
/**
176
* Returns the password parameter name.
177
*
178
* @return the password parameter name
179
*/
180
public String getPasswordParam();
181
182
/**
183
* Sets the password parameter name.
184
*
185
* @param passwordParam the password parameter name to set
186
*/
187
public void setPasswordParam(String passwordParam);
188
189
/**
190
* Returns the remember me parameter name.
191
*
192
* @return the remember me parameter name
193
*/
194
public String getRememberMeParam();
195
196
/**
197
* Sets the remember me parameter name.
198
*
199
* @param rememberMeParam the remember me parameter name to set
200
*/
201
public void setRememberMeParam(String rememberMeParam);
202
203
/**
204
* Returns the failure key attribute name.
205
*
206
* @return the failure key attribute name
207
*/
208
public String getFailureKeyAttribute();
209
210
/**
211
* Sets the failure key attribute name.
212
*
213
* @param failureKeyAttribute the failure key attribute name to set
214
*/
215
public void setFailureKeyAttribute(String failureKeyAttribute);
216
217
/**
218
* Determines if the request is a login submission.
219
*
220
* @param request the servlet request
221
* @param response the servlet response
222
* @return true if this is a login submission
223
*/
224
protected boolean isLoginSubmission(ServletRequest request, ServletResponse response);
225
226
/**
227
* Creates a UsernamePasswordToken from the request parameters.
228
*
229
* @param request the servlet request
230
* @param response the servlet response
231
* @return the created authentication token
232
*/
233
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response);
234
235
/**
236
* Extracts the username from the request.
237
*
238
* @param request the servlet request
239
* @return the username value
240
*/
241
protected String getUsername(ServletRequest request);
242
243
/**
244
* Extracts the password from the request.
245
*
246
* @param request the servlet request
247
* @return the password value
248
*/
249
protected String getPassword(ServletRequest request);
250
251
/**
252
* Determines if "remember me" is requested.
253
*
254
* @param request the servlet request
255
* @return true if remember me is requested
256
*/
257
protected boolean isRememberMe(ServletRequest request);
258
259
/**
260
* Handles authentication failure by setting error attributes.
261
*
262
* @param token the failed authentication token
263
* @param ae the authentication exception
264
* @param request the servlet request
265
* @param response the servlet response
266
* @return true if failure was handled
267
*/
268
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae,
269
ServletRequest request, ServletResponse response);
270
271
/**
272
* Sets the authentication failure exception in the request for error display.
273
*
274
* @param request the servlet request
275
* @param ae the authentication exception
276
*/
277
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae);
278
}
279
```
280
281
### HTTP Authentication Filters
282
283
Filters for HTTP-based authentication mechanisms including Basic and Bearer token authentication.
284
285
```java { .api }
286
abstract class HttpAuthenticationFilter extends AuthenticatingFilter {
287
/** HTTP Basic authentication scheme */
288
public static final String BASIC_SCHEME = "Basic";
289
290
/** HTTP Bearer authentication scheme */
291
public static final String BEARER_SCHEME = "Bearer";
292
293
/** HTTP Authorization header name */
294
public static final String AUTHORIZATION_HEADER = "Authorization";
295
296
/** HTTP WWW-Authenticate header name */
297
public static final String AUTHENTICATE_HEADER = "WWW-Authenticate";
298
299
/**
300
* Returns the authentication scheme name.
301
*
302
* @return the authentication scheme
303
*/
304
protected abstract String getAuthcScheme();
305
306
/**
307
* Returns the realm name for authentication challenges.
308
*
309
* @return the realm name
310
*/
311
protected String getRealm();
312
313
/**
314
* Sets the realm name for authentication challenges.
315
*
316
* @param realm the realm name to set
317
*/
318
protected void setRealm(String realm);
319
320
/**
321
* Determines if the request contains authentication credentials.
322
*
323
* @param request the servlet request
324
* @return true if credentials are present
325
*/
326
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response);
327
328
/**
329
* Sends an authentication challenge to the client.
330
*
331
* @param response the servlet response
332
* @return false to stop further processing
333
*/
334
protected boolean sendChallenge(ServletRequest request, ServletResponse response);
335
336
/**
337
* Builds the WWW-Authenticate header value.
338
*
339
* @return the authentication challenge string
340
*/
341
protected String getAuthenticateHeader();
342
}
343
```
344
345
```java { .api }
346
class BasicHttpAuthenticationFilter extends HttpAuthenticationFilter {
347
/** HTTP Basic authentication scheme constant */
348
public static final String BASIC_SCHEME = "Basic";
349
350
/**
351
* Creates a new BasicHttpAuthenticationFilter.
352
*/
353
public BasicHttpAuthenticationFilter();
354
355
/**
356
* Returns the Basic authentication scheme.
357
*
358
* @return "Basic"
359
*/
360
protected String getAuthcScheme();
361
362
/**
363
* Creates a UsernamePasswordToken from Basic authentication header.
364
*
365
* @param request the servlet request
366
* @param response the servlet response
367
* @return the authentication token
368
*/
369
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response);
370
371
/**
372
* Extracts username and password from Authorization header.
373
*
374
* @param authorizationHeader the Authorization header value
375
* @param request the servlet request
376
* @return array containing [username, password]
377
*/
378
protected String[] getPrincipalsAndCredentials(String authorizationHeader, ServletRequest request);
379
380
/**
381
* Handles access denied by sending Basic authentication challenge.
382
*
383
* @param request the servlet request
384
* @param response the servlet response
385
* @return false to stop processing
386
* @throws Exception if challenge sending fails
387
*/
388
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
389
390
/**
391
* Decodes Base64-encoded Basic authentication credentials.
392
*
393
* @param encoded the Base64-encoded credentials
394
* @return the decoded credentials string
395
*/
396
private String decodeBase64(String encoded);
397
}
398
```
399
400
```java { .api }
401
class BearerHttpAuthenticationFilter extends HttpAuthenticationFilter {
402
/** HTTP Bearer authentication scheme constant */
403
public static final String BEARER_SCHEME = "Bearer";
404
405
/**
406
* Creates a new BearerHttpAuthenticationFilter.
407
*/
408
public BearerHttpAuthenticationFilter();
409
410
/**
411
* Returns the Bearer authentication scheme.
412
*
413
* @return "Bearer"
414
*/
415
protected String getAuthcScheme();
416
417
/**
418
* Creates a BearerToken from the Authorization header.
419
*
420
* @param request the servlet request
421
* @param response the servlet response
422
* @return the bearer authentication token
423
*/
424
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response);
425
426
/**
427
* Extracts the bearer token from the Authorization header.
428
*
429
* @param authorizationHeader the Authorization header value
430
* @return the bearer token string
431
*/
432
protected String getBearerToken(String authorizationHeader);
433
434
/**
435
* Handles access denied by sending Bearer authentication challenge.
436
*
437
* @param request the servlet request
438
* @param response the servlet response
439
* @return false to stop processing
440
* @throws Exception if challenge sending fails
441
*/
442
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
443
}
444
```
445
446
### Anonymous and User Filters
447
448
Filters for handling anonymous access and ensuring user authentication (including remembered users).
449
450
```java { .api }
451
class AnonymousFilter extends PathMatchingFilter {
452
/**
453
* Creates a new AnonymousFilter.
454
*/
455
public AnonymousFilter();
456
457
/**
458
* Always allows access and ensures an anonymous subject is available.
459
*
460
* @param request the servlet request
461
* @param response the servlet response
462
* @return always true
463
* @throws Exception if processing fails
464
*/
465
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
466
throws Exception;
467
}
468
```
469
470
```java { .api }
471
class UserFilter extends AccessControlFilter {
472
/**
473
* Creates a new UserFilter.
474
*/
475
public UserFilter();
476
477
/**
478
* Determines if access is allowed for known users (authenticated or remembered).
479
*
480
* @param request the servlet request
481
* @param response the servlet response
482
* @param mappedValue the configuration for this path
483
* @return true if user is known (authenticated or remembered)
484
*/
485
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue);
486
487
/**
488
* Handles access denied by redirecting unknown users to login.
489
*
490
* @param request the servlet request
491
* @param response the servlet response
492
* @return false to stop processing
493
* @throws Exception if redirect fails
494
*/
495
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
496
}
497
```
498
499
### Pass-Through Authentication Filter
500
501
Filter that allows requests to pass through without requiring authentication while still providing authentication opportunities.
502
503
```java { .api }
504
class PassThruAuthenticationFilter extends AuthenticationFilter {
505
/**
506
* Creates a new PassThruAuthenticationFilter.
507
*/
508
public PassThruAuthenticationFilter();
509
510
/**
511
* Always allows access regardless of authentication status.
512
*
513
* @param request the servlet request
514
* @param response the servlet response
515
* @param mappedValue the configuration for this path
516
* @return always true
517
*/
518
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue);
519
520
/**
521
* Never called since access is always allowed.
522
*
523
* @param request the servlet request
524
* @param response the servlet response
525
* @return always true
526
* @throws Exception never thrown
527
*/
528
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
529
}
530
```
531
532
### Logout Filter
533
534
Filter for handling user logout requests and cleanup of authentication state.
535
536
```java { .api }
537
class LogoutFilter extends AdviceFilter {
538
/** Default logout redirect URL */
539
public static final String DEFAULT_REDIRECT_URL = "/";
540
541
/**
542
* Creates a new LogoutFilter with default redirect URL.
543
*/
544
public LogoutFilter();
545
546
/**
547
* Returns the URL to redirect to after logout.
548
*
549
* @return the redirect URL
550
*/
551
public String getRedirectUrl();
552
553
/**
554
* Sets the URL to redirect to after logout.
555
*
556
* @param redirectUrl the redirect URL to set
557
*/
558
public void setRedirectUrl(String redirectUrl);
559
560
/**
561
* Processes logout requests by logging out the current subject.
562
*
563
* @param request the servlet request
564
* @param response the servlet response
565
* @return true to continue processing, false to stop
566
* @throws Exception if logout processing fails
567
*/
568
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception;
569
570
/**
571
* Logs out the current subject and cleans up authentication state.
572
*
573
* @param request the servlet request
574
* @param response the servlet response
575
* @throws Exception if logout fails
576
*/
577
protected void logout(ServletRequest request, ServletResponse response) throws Exception;
578
579
/**
580
* Redirects to the configured redirect URL after logout.
581
*
582
* @param request the servlet request
583
* @param response the servlet response
584
* @throws IOException if redirect fails
585
*/
586
protected void issueRedirect(ServletRequest request, ServletResponse response) throws IOException;
587
}
588
```
589
590
## Usage Examples
591
592
### Form Authentication Configuration
593
594
```java
595
// web.xml or programmatic filter chain configuration
596
public void configureFormAuthentication() {
597
FormAuthenticationFilter formFilter = new FormAuthenticationFilter();
598
formFilter.setLoginUrl("/login");
599
formFilter.setSuccessUrl("/dashboard");
600
formFilter.setUsernameParam("email");
601
formFilter.setPasswordParam("password");
602
formFilter.setRememberMeParam("remember");
603
formFilter.setFailureKeyAttribute("loginError");
604
605
// Configure in filter chain
606
DefaultFilterChainManager manager = new DefaultFilterChainManager();
607
manager.addFilter("formAuthc", formFilter);
608
manager.createChain("/login", "authc");
609
manager.createChain("/secure/**", "formAuthc");
610
}
611
612
// Login form HTML
613
/*
614
<form action="/login" method="post">
615
<input type="text" name="email" placeholder="Email">
616
<input type="password" name="password" placeholder="Password">
617
<input type="checkbox" name="remember" value="true"> Remember Me
618
<input type="submit" value="Login">
619
</form>
620
*/
621
```
622
623
### HTTP Basic Authentication Setup
624
625
```java
626
public void configureBasicAuthentication() {
627
BasicHttpAuthenticationFilter basicFilter = new BasicHttpAuthenticationFilter();
628
basicFilter.setRealm("My Application");
629
630
// For API endpoints
631
DefaultFilterChainManager manager = new DefaultFilterChainManager();
632
manager.addFilter("basicAuthc", basicFilter);
633
manager.createChain("/api/**", "basicAuthc");
634
manager.createChain("/api/public/**", "anon");
635
}
636
637
// Client usage example
638
/*
639
// HTTP request with Basic authentication
640
GET /api/users HTTP/1.1
641
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
642
Host: example.com
643
*/
644
```
645
646
### Bearer Token Authentication
647
648
```java
649
public void configureBearerAuthentication() {
650
BearerHttpAuthenticationFilter bearerFilter = new BearerHttpAuthenticationFilter();
651
bearerFilter.setRealm("API Access");
652
653
// Custom realm for token validation
654
TokenValidatingRealm tokenRealm = new TokenValidatingRealm();
655
656
DefaultFilterChainManager manager = new DefaultFilterChainManager();
657
manager.addFilter("bearerAuthc", bearerFilter);
658
manager.createChain("/api/v2/**", "bearerAuthc");
659
}
660
661
// Client usage example
662
/*
663
// HTTP request with Bearer token
664
GET /api/v2/users HTTP/1.1
665
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
666
Host: example.com
667
*/
668
```
669
670
### Mixed Authentication Strategy
671
672
```java
673
public void configureMixedAuthentication() {
674
DefaultFilterChainManager manager = new DefaultFilterChainManager();
675
676
// Configure different authentication methods
677
FormAuthenticationFilter formFilter = new FormAuthenticationFilter();
678
BasicHttpAuthenticationFilter basicFilter = new BasicHttpAuthenticationFilter();
679
LogoutFilter logoutFilter = new LogoutFilter();
680
logoutFilter.setRedirectUrl("/login?logout=true");
681
682
manager.addFilter("formAuthc", formFilter);
683
manager.addFilter("basicAuthc", basicFilter);
684
manager.addFilter("logout", logoutFilter);
685
686
// Different filter chains for different URL patterns
687
manager.createChain("/login", "authc");
688
manager.createChain("/logout", "logout");
689
manager.createChain("/api/**", "basicAuthc"); // API uses Basic auth
690
manager.createChain("/admin/**", "formAuthc, roles[admin]"); // Admin uses form auth
691
manager.createChain("/user/**", "user"); // Any known user
692
manager.createChain("/**", "anon"); // Everything else anonymous
693
}
694
```
695
696
### Custom Authentication Filter
697
698
```java
699
public class JwtAuthenticationFilter extends HttpAuthenticationFilter {
700
private static final String JWT_SCHEME = "Bearer";
701
702
@Override
703
protected String getAuthcScheme() {
704
return JWT_SCHEME;
705
}
706
707
@Override
708
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
709
String authHeader = getAuthzHeader(request);
710
if (authHeader != null && authHeader.startsWith(JWT_SCHEME + " ")) {
711
String jwt = authHeader.substring(7); // Remove "Bearer " prefix
712
return new JwtAuthenticationToken(jwt);
713
}
714
return null;
715
}
716
717
@Override
718
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
719
boolean loginAttempt = isLoginAttempt(request, response);
720
if (loginAttempt) {
721
return executeLogin(request, response);
722
} else {
723
return sendChallenge(request, response);
724
}
725
}
726
727
private String getAuthzHeader(ServletRequest request) {
728
HttpServletRequest httpRequest = (HttpServletRequest) request;
729
return httpRequest.getHeader(AUTHORIZATION_HEADER);
730
}
731
}
732
733
// Custom JWT authentication token
734
public class JwtAuthenticationToken implements AuthenticationToken {
735
private final String jwt;
736
737
public JwtAuthenticationToken(String jwt) {
738
this.jwt = jwt;
739
}
740
741
@Override
742
public Object getPrincipal() {
743
return jwt;
744
}
745
746
@Override
747
public Object getCredentials() {
748
return jwt;
749
}
750
}
751
```