Web support module for Apache Shiro providing servlet filters, session management, and web-specific authentication and authorization features
—
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.
Foundation classes providing common authentication functionality and templates for implementing custom authentication mechanisms.
abstract class AuthenticationFilter extends AccessControlFilter {
/** Default login URL */
public static final String DEFAULT_LOGIN_URL = "/login";
/** Default URL to redirect to after successful login */
public static final String DEFAULT_SUCCESS_URL = "/";
/**
* Returns the URL to redirect to after successful authentication.
*
* @return the success URL
*/
public String getSuccessUrl();
/**
* Sets the URL to redirect to after successful authentication.
*
* @param successUrl the success URL to set
*/
public void setSuccessUrl(String successUrl);
/**
* Template method determining if access is allowed without authentication.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return true if access is allowed
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue);
/**
* Determines if the current request is a login request.
*
* @param request the servlet request
* @param response the servlet response
* @return true if this is a login request
*/
protected boolean isLoginRequest(ServletRequest request, ServletResponse response);
/**
* Determines if a login attempt should be made for this request.
*
* @param request the servlet request
* @param response the servlet response
* @return true if login should be attempted
*/
protected boolean isLoginSubmission(ServletRequest request, ServletResponse response);
}abstract class AuthenticatingFilter extends AuthenticationFilter {
/** Default username parameter name */
public static final String DEFAULT_USERNAME_PARAM = "username";
/** Default password parameter name */
public static final String DEFAULT_PASSWORD_PARAM = "password";
/** Default remember me parameter name */
public static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";
/**
* Handles access denied scenarios by attempting authentication.
*
* @param request the servlet request
* @param response the servlet response
* @return true if authentication succeeded or was handled
* @throws Exception if authentication processing fails
*/
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
/**
* Executes the authentication attempt.
*
* @param request the servlet request
* @param response the servlet response
* @return true if authentication succeeded
* @throws Exception if authentication fails
*/
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception;
/**
* Creates an authentication token from the request.
*
* @param request the servlet request
* @param response the servlet response
* @return the authentication token
*/
protected abstract AuthenticationToken createToken(ServletRequest request, ServletResponse response);
/**
* Handles successful authentication.
*
* @param token the authentication token
* @param subject the authenticated subject
* @param request the servlet request
* @param response the servlet response
* @return true to continue processing
* @throws Exception if success handling fails
*/
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception;
/**
* Handles failed authentication.
*
* @param token the authentication token that failed
* @param ae the authentication exception
* @param request the servlet request
* @param response the servlet response
* @return true if failure was handled and processing should continue
*/
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae,
ServletRequest request, ServletResponse response);
/**
* Redirects to the success URL after successful authentication.
*
* @param request the servlet request
* @param response the servlet response
* @throws IOException if redirect fails
*/
protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws IOException;
}Filter for handling HTML form-based authentication with username/password credentials and remember-me functionality.
class FormAuthenticationFilter extends AuthenticatingFilter {
/** Default username parameter name */
public static final String DEFAULT_USERNAME_PARAM = "username";
/** Default password parameter name */
public static final String DEFAULT_PASSWORD_PARAM = "password";
/** Default remember me parameter name */
public static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";
/** Default error attribute name */
public static final String DEFAULT_ERROR_KEY_ATTRIBUTE_NAME = "shiroLoginFailure";
/**
* Creates a new FormAuthenticationFilter.
*/
public FormAuthenticationFilter();
/**
* Returns the username parameter name.
*
* @return the username parameter name
*/
public String getUsernameParam();
/**
* Sets the username parameter name.
*
* @param usernameParam the username parameter name to set
*/
public void setUsernameParam(String usernameParam);
/**
* Returns the password parameter name.
*
* @return the password parameter name
*/
public String getPasswordParam();
/**
* Sets the password parameter name.
*
* @param passwordParam the password parameter name to set
*/
public void setPasswordParam(String passwordParam);
/**
* Returns the remember me parameter name.
*
* @return the remember me parameter name
*/
public String getRememberMeParam();
/**
* Sets the remember me parameter name.
*
* @param rememberMeParam the remember me parameter name to set
*/
public void setRememberMeParam(String rememberMeParam);
/**
* Returns the failure key attribute name.
*
* @return the failure key attribute name
*/
public String getFailureKeyAttribute();
/**
* Sets the failure key attribute name.
*
* @param failureKeyAttribute the failure key attribute name to set
*/
public void setFailureKeyAttribute(String failureKeyAttribute);
/**
* Determines if the request is a login submission.
*
* @param request the servlet request
* @param response the servlet response
* @return true if this is a login submission
*/
protected boolean isLoginSubmission(ServletRequest request, ServletResponse response);
/**
* Creates a UsernamePasswordToken from the request parameters.
*
* @param request the servlet request
* @param response the servlet response
* @return the created authentication token
*/
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response);
/**
* Extracts the username from the request.
*
* @param request the servlet request
* @return the username value
*/
protected String getUsername(ServletRequest request);
/**
* Extracts the password from the request.
*
* @param request the servlet request
* @return the password value
*/
protected String getPassword(ServletRequest request);
/**
* Determines if "remember me" is requested.
*
* @param request the servlet request
* @return true if remember me is requested
*/
protected boolean isRememberMe(ServletRequest request);
/**
* Handles authentication failure by setting error attributes.
*
* @param token the failed authentication token
* @param ae the authentication exception
* @param request the servlet request
* @param response the servlet response
* @return true if failure was handled
*/
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae,
ServletRequest request, ServletResponse response);
/**
* Sets the authentication failure exception in the request for error display.
*
* @param request the servlet request
* @param ae the authentication exception
*/
protected void setFailureAttribute(ServletRequest request, AuthenticationException ae);
}Filters for HTTP-based authentication mechanisms including Basic and Bearer token authentication.
abstract class HttpAuthenticationFilter extends AuthenticatingFilter {
/** HTTP Basic authentication scheme */
public static final String BASIC_SCHEME = "Basic";
/** HTTP Bearer authentication scheme */
public static final String BEARER_SCHEME = "Bearer";
/** HTTP Authorization header name */
public static final String AUTHORIZATION_HEADER = "Authorization";
/** HTTP WWW-Authenticate header name */
public static final String AUTHENTICATE_HEADER = "WWW-Authenticate";
/**
* Returns the authentication scheme name.
*
* @return the authentication scheme
*/
protected abstract String getAuthcScheme();
/**
* Returns the realm name for authentication challenges.
*
* @return the realm name
*/
protected String getRealm();
/**
* Sets the realm name for authentication challenges.
*
* @param realm the realm name to set
*/
protected void setRealm(String realm);
/**
* Determines if the request contains authentication credentials.
*
* @param request the servlet request
* @return true if credentials are present
*/
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response);
/**
* Sends an authentication challenge to the client.
*
* @param response the servlet response
* @return false to stop further processing
*/
protected boolean sendChallenge(ServletRequest request, ServletResponse response);
/**
* Builds the WWW-Authenticate header value.
*
* @return the authentication challenge string
*/
protected String getAuthenticateHeader();
}class BasicHttpAuthenticationFilter extends HttpAuthenticationFilter {
/** HTTP Basic authentication scheme constant */
public static final String BASIC_SCHEME = "Basic";
/**
* Creates a new BasicHttpAuthenticationFilter.
*/
public BasicHttpAuthenticationFilter();
/**
* Returns the Basic authentication scheme.
*
* @return "Basic"
*/
protected String getAuthcScheme();
/**
* Creates a UsernamePasswordToken from Basic authentication header.
*
* @param request the servlet request
* @param response the servlet response
* @return the authentication token
*/
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response);
/**
* Extracts username and password from Authorization header.
*
* @param authorizationHeader the Authorization header value
* @param request the servlet request
* @return array containing [username, password]
*/
protected String[] getPrincipalsAndCredentials(String authorizationHeader, ServletRequest request);
/**
* Handles access denied by sending Basic authentication challenge.
*
* @param request the servlet request
* @param response the servlet response
* @return false to stop processing
* @throws Exception if challenge sending fails
*/
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
/**
* Decodes Base64-encoded Basic authentication credentials.
*
* @param encoded the Base64-encoded credentials
* @return the decoded credentials string
*/
private String decodeBase64(String encoded);
}class BearerHttpAuthenticationFilter extends HttpAuthenticationFilter {
/** HTTP Bearer authentication scheme constant */
public static final String BEARER_SCHEME = "Bearer";
/**
* Creates a new BearerHttpAuthenticationFilter.
*/
public BearerHttpAuthenticationFilter();
/**
* Returns the Bearer authentication scheme.
*
* @return "Bearer"
*/
protected String getAuthcScheme();
/**
* Creates a BearerToken from the Authorization header.
*
* @param request the servlet request
* @param response the servlet response
* @return the bearer authentication token
*/
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response);
/**
* Extracts the bearer token from the Authorization header.
*
* @param authorizationHeader the Authorization header value
* @return the bearer token string
*/
protected String getBearerToken(String authorizationHeader);
/**
* Handles access denied by sending Bearer authentication challenge.
*
* @param request the servlet request
* @param response the servlet response
* @return false to stop processing
* @throws Exception if challenge sending fails
*/
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
}Filters for handling anonymous access and ensuring user authentication (including remembered users).
class AnonymousFilter extends PathMatchingFilter {
/**
* Creates a new AnonymousFilter.
*/
public AnonymousFilter();
/**
* Always allows access and ensures an anonymous subject is available.
*
* @param request the servlet request
* @param response the servlet response
* @return always true
* @throws Exception if processing fails
*/
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
}class UserFilter extends AccessControlFilter {
/**
* Creates a new UserFilter.
*/
public UserFilter();
/**
* Determines if access is allowed for known users (authenticated or remembered).
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return true if user is known (authenticated or remembered)
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue);
/**
* Handles access denied by redirecting unknown users to login.
*
* @param request the servlet request
* @param response the servlet response
* @return false to stop processing
* @throws Exception if redirect fails
*/
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
}Filter that allows requests to pass through without requiring authentication while still providing authentication opportunities.
class PassThruAuthenticationFilter extends AuthenticationFilter {
/**
* Creates a new PassThruAuthenticationFilter.
*/
public PassThruAuthenticationFilter();
/**
* Always allows access regardless of authentication status.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return always true
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue);
/**
* Never called since access is always allowed.
*
* @param request the servlet request
* @param response the servlet response
* @return always true
* @throws Exception never thrown
*/
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;
}Filter for handling user logout requests and cleanup of authentication state.
class LogoutFilter extends AdviceFilter {
/** Default logout redirect URL */
public static final String DEFAULT_REDIRECT_URL = "/";
/**
* Creates a new LogoutFilter with default redirect URL.
*/
public LogoutFilter();
/**
* Returns the URL to redirect to after logout.
*
* @return the redirect URL
*/
public String getRedirectUrl();
/**
* Sets the URL to redirect to after logout.
*
* @param redirectUrl the redirect URL to set
*/
public void setRedirectUrl(String redirectUrl);
/**
* Processes logout requests by logging out the current subject.
*
* @param request the servlet request
* @param response the servlet response
* @return true to continue processing, false to stop
* @throws Exception if logout processing fails
*/
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception;
/**
* Logs out the current subject and cleans up authentication state.
*
* @param request the servlet request
* @param response the servlet response
* @throws Exception if logout fails
*/
protected void logout(ServletRequest request, ServletResponse response) throws Exception;
/**
* Redirects to the configured redirect URL after logout.
*
* @param request the servlet request
* @param response the servlet response
* @throws IOException if redirect fails
*/
protected void issueRedirect(ServletRequest request, ServletResponse response) throws IOException;
}// web.xml or programmatic filter chain configuration
public void configureFormAuthentication() {
FormAuthenticationFilter formFilter = new FormAuthenticationFilter();
formFilter.setLoginUrl("/login");
formFilter.setSuccessUrl("/dashboard");
formFilter.setUsernameParam("email");
formFilter.setPasswordParam("password");
formFilter.setRememberMeParam("remember");
formFilter.setFailureKeyAttribute("loginError");
// Configure in filter chain
DefaultFilterChainManager manager = new DefaultFilterChainManager();
manager.addFilter("formAuthc", formFilter);
manager.createChain("/login", "authc");
manager.createChain("/secure/**", "formAuthc");
}
// Login form HTML
/*
<form action="/login" method="post">
<input type="text" name="email" placeholder="Email">
<input type="password" name="password" placeholder="Password">
<input type="checkbox" name="remember" value="true"> Remember Me
<input type="submit" value="Login">
</form>
*/public void configureBasicAuthentication() {
BasicHttpAuthenticationFilter basicFilter = new BasicHttpAuthenticationFilter();
basicFilter.setRealm("My Application");
// For API endpoints
DefaultFilterChainManager manager = new DefaultFilterChainManager();
manager.addFilter("basicAuthc", basicFilter);
manager.createChain("/api/**", "basicAuthc");
manager.createChain("/api/public/**", "anon");
}
// Client usage example
/*
// HTTP request with Basic authentication
GET /api/users HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Host: example.com
*/public void configureBearerAuthentication() {
BearerHttpAuthenticationFilter bearerFilter = new BearerHttpAuthenticationFilter();
bearerFilter.setRealm("API Access");
// Custom realm for token validation
TokenValidatingRealm tokenRealm = new TokenValidatingRealm();
DefaultFilterChainManager manager = new DefaultFilterChainManager();
manager.addFilter("bearerAuthc", bearerFilter);
manager.createChain("/api/v2/**", "bearerAuthc");
}
// Client usage example
/*
// HTTP request with Bearer token
GET /api/v2/users HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Host: example.com
*/public void configureMixedAuthentication() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
// Configure different authentication methods
FormAuthenticationFilter formFilter = new FormAuthenticationFilter();
BasicHttpAuthenticationFilter basicFilter = new BasicHttpAuthenticationFilter();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/login?logout=true");
manager.addFilter("formAuthc", formFilter);
manager.addFilter("basicAuthc", basicFilter);
manager.addFilter("logout", logoutFilter);
// Different filter chains for different URL patterns
manager.createChain("/login", "authc");
manager.createChain("/logout", "logout");
manager.createChain("/api/**", "basicAuthc"); // API uses Basic auth
manager.createChain("/admin/**", "formAuthc, roles[admin]"); // Admin uses form auth
manager.createChain("/user/**", "user"); // Any known user
manager.createChain("/**", "anon"); // Everything else anonymous
}public class JwtAuthenticationFilter extends HttpAuthenticationFilter {
private static final String JWT_SCHEME = "Bearer";
@Override
protected String getAuthcScheme() {
return JWT_SCHEME;
}
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String authHeader = getAuthzHeader(request);
if (authHeader != null && authHeader.startsWith(JWT_SCHEME + " ")) {
String jwt = authHeader.substring(7); // Remove "Bearer " prefix
return new JwtAuthenticationToken(jwt);
}
return null;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
boolean loginAttempt = isLoginAttempt(request, response);
if (loginAttempt) {
return executeLogin(request, response);
} else {
return sendChallenge(request, response);
}
}
private String getAuthzHeader(ServletRequest request) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
return httpRequest.getHeader(AUTHORIZATION_HEADER);
}
}
// Custom JWT authentication token
public class JwtAuthenticationToken implements AuthenticationToken {
private final String jwt;
public JwtAuthenticationToken(String jwt) {
this.jwt = jwt;
}
@Override
public Object getPrincipal() {
return jwt;
}
@Override
public Object getCredentials() {
return jwt;
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-shiro--shiro-web