Web support module for Apache Shiro providing servlet filters, session management, and web-specific authentication and authorization features
—
Access control filters for Apache Shiro web applications providing role-based and permission-based authorization, SSL enforcement, host/port restrictions, and HTTP method-specific permissions. These filters enable fine-grained access control policies that can be applied to different URL patterns and request types.
Foundation class for all authorization filters providing common access control functionality and templates for implementing custom authorization logic.
abstract class AuthorizationFilter extends AccessControlFilter {
/**
* Always returns false since authorization filters require authentication first.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return always false
* @throws Exception if access check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Template method for determining if the subject is authorized.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return true if subject is authorized
* @throws Exception if authorization check fails
*/
protected abstract boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Returns the current subject for authorization checks.
*
* @param request the servlet request
* @param response the servlet response
* @return the current Subject instance
*/
protected Subject getSubject(ServletRequest request, ServletResponse response);
}Filters for enforcing permission-based access control using Shiro's permission system.
class PermissionsAuthorizationFilter extends AuthorizationFilter {
/**
* Creates a new PermissionsAuthorizationFilter.
*/
public PermissionsAuthorizationFilter();
/**
* Determines if the current subject has the required permissions.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue comma-delimited string of required permissions
* @return true if subject has all required permissions
* @throws Exception if permission check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Converts the mapped value to an array of required permissions.
*
* @param mappedValue the permission configuration (String or String[])
* @return array of permission strings
*/
public String[] getPerms(Object mappedValue);
}class HttpMethodPermissionFilter extends PermissionsAuthorizationFilter {
/**
* Creates a new HttpMethodPermissionFilter.
*/
public HttpMethodPermissionFilter();
/**
* Determines access by checking permissions based on HTTP method.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the permission configuration
* @return true if subject has permission for the HTTP method
* @throws Exception if permission check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Returns the permission action based on HTTP method.
*
* @param request the servlet request
* @return the action string (read, create, update, delete)
*/
protected String getHttpMethodAction(ServletRequest request);
/**
* Builds permission strings by combining base permissions with HTTP method actions.
*
* @param mappedValue the base permission configuration
* @param request the servlet request
* @return array of method-specific permission strings
*/
private String[] buildPermissions(Object mappedValue, ServletRequest request);
}Filters for enforcing role-based access control using Shiro's role system.
class RolesAuthorizationFilter extends AuthorizationFilter {
/**
* Creates a new RolesAuthorizationFilter.
*/
public RolesAuthorizationFilter();
/**
* Determines if the current subject has the required roles.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue comma-delimited string of required roles
* @return true if subject has all required roles
* @throws Exception if role check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Converts the mapped value to an array of required roles.
*
* @param mappedValue the role configuration (String or String[])
* @return array of role strings
*/
public String[] getRoles(Object mappedValue);
}Filters for enforcing secure connections and restricting access based on connection characteristics.
class PortFilter extends AccessControlFilter {
/** Default HTTP port */
public static final int DEFAULT_HTTP_PORT = 80;
/** Default HTTPS port */
public static final int DEFAULT_HTTPS_PORT = 443;
/**
* Creates a new PortFilter with default HTTP port.
*/
public PortFilter();
/**
* Returns the required port number.
*
* @return the port number
*/
public int getPort();
/**
* Sets the required port number.
*
* @param port the port number to require
*/
public void setPort(int port);
/**
* Determines if access is allowed based on the request port.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return true if request is on the required port
* @throws Exception if port check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Handles access denied by redirecting to the correct port.
*
* @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;
/**
* Returns the port from the request.
*
* @param request the servlet request
* @return the request port number
*/
protected int getPort(ServletRequest request);
/**
* Builds the redirect URL for the required port.
*
* @param scheme the URL scheme (http/https)
* @param host the host name
* @param port the port number
* @param uri the request URI
* @return the redirect URL
*/
private String buildRedirectUrl(String scheme, String host, int port, String uri);
}class SslFilter extends PortFilter {
/** Default HTTPS port */
public static final int DEFAULT_HTTPS_PORT = 443;
/**
* Creates a new SslFilter configured for HTTPS port 443.
*/
public SslFilter();
/**
* Determines if access is allowed by checking for HTTPS connection.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue the configuration for this path
* @return true if request is over HTTPS
* @throws Exception if SSL check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Determines if the request is over a secure (HTTPS) connection.
*
* @param request the servlet request
* @return true if request is secure
*/
protected boolean isSecure(ServletRequest request);
/**
* Returns the HTTPS scheme.
*
* @return "https"
*/
protected String getScheme();
}Filter for restricting access based on client host addresses and hostnames.
class HostFilter extends AuthorizationFilter {
/**
* Creates a new HostFilter.
*/
public HostFilter();
/**
* Determines if access is allowed based on the client host.
*
* @param request the servlet request
* @param response the servlet response
* @param mappedValue comma-delimited string of allowed hosts
* @return true if client host is allowed
* @throws Exception if host check fails
*/
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception;
/**
* Checks if the client host matches any of the allowed hosts.
*
* @param hostAddress the client host address
* @param allowedHosts array of allowed host patterns
* @return true if host is allowed
*/
protected boolean isHostAllowed(String hostAddress, String[] allowedHosts);
/**
* Converts the mapped value to an array of allowed hosts.
*
* @param mappedValue the host configuration (String or String[])
* @return array of allowed host strings
*/
private String[] toHostArray(Object mappedValue);
/**
* Returns the client host address from the request.
*
* @param request the servlet request
* @return the client host address
*/
protected String getHost(ServletRequest request);
}public void configurePermissionFilters() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
// Configure permission filter
PermissionsAuthorizationFilter permsFilter = new PermissionsAuthorizationFilter();
manager.addFilter("perms", permsFilter);
// Define permission-based access rules
manager.createChain("/users/**", "authc, perms[user:read]");
manager.createChain("/users/create", "authc, perms[user:create]");
manager.createChain("/users/*/edit", "authc, perms[user:update]");
manager.createChain("/users/*/delete", "authc, perms[user:delete]");
manager.createChain("/admin/**", "authc, perms[admin:*]");
// Multiple permissions (all required)
manager.createChain("/reports/**", "authc, perms[report:read,report:export]");
}
// In your realm or security manager
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// Add permissions based on user
if ("admin".equals(username)) {
info.addStringPermission("admin:*");
info.addStringPermission("user:*");
info.addStringPermission("report:*");
} else if ("manager".equals(username)) {
info.addStringPermission("user:read");
info.addStringPermission("user:update");
info.addStringPermission("report:read");
} else {
info.addStringPermission("user:read");
}
return info;
}
}public void configureRoleFilters() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
// Configure role filter
RolesAuthorizationFilter rolesFilter = new RolesAuthorizationFilter();
manager.addFilter("roles", rolesFilter);
// Define role-based access rules
manager.createChain("/admin/**", "authc, roles[admin]");
manager.createChain("/manager/**", "authc, roles[manager]");
manager.createChain("/user/**", "authc, roles[user]");
// Multiple roles (all required)
manager.createChain("/sensitive/**", "authc, roles[admin,security]");
// Complex combinations
manager.createChain("/reports/financial/**", "authc, roles[finance], perms[report:financial]");
}
// Role assignment in realm
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// Assign roles based on user
User user = userService.findByUsername(username);
info.setRoles(user.getRoles());
return info;
}public void configureHttpMethodPermissions() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
// Configure HTTP method permission filter
HttpMethodPermissionFilter httpMethodFilter = new HttpMethodPermissionFilter();
manager.addFilter("rest", httpMethodFilter);
// RESTful API permissions based on HTTP methods
// GET /api/users -> requires user:read
// POST /api/users -> requires user:create
// PUT /api/users/123 -> requires user:update
// DELETE /api/users/123 -> requires user:delete
manager.createChain("/api/users/**", "authc, rest[user]");
manager.createChain("/api/orders/**", "authc, rest[order]");
manager.createChain("/api/products/**", "authc, rest[product]");
}
// The HttpMethodPermissionFilter automatically maps:
// GET -> :read permission
// POST -> :create permission
// PUT -> :update permission
// DELETE -> :delete permissionpublic void configureSecurityFilters() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
// Require SSL for sensitive areas
SslFilter sslFilter = new SslFilter();
sslFilter.setPort(8443); // Custom HTTPS port
manager.addFilter("ssl", sslFilter);
// Restrict access by host
HostFilter hostFilter = new HostFilter();
manager.addFilter("host", hostFilter);
// Configure secure access rules
manager.createChain("/admin/**", "ssl, authc, roles[admin]");
manager.createChain("/api/internal/**", "host[192.168.1.0/24,10.0.0.0/8], authc");
manager.createChain("/login", "ssl");
manager.createChain("/secure/**", "ssl, authc");
// Port-specific access
PortFilter httpPortFilter = new PortFilter();
httpPortFilter.setPort(8080);
manager.addFilter("httpPort", httpPortFilter);
manager.createChain("/public/**", "httpPort");
}public class TimeBasedAccessFilter extends AuthorizationFilter {
private int startHour = 9; // 9 AM
private int endHour = 17; // 5 PM
public void setStartHour(int startHour) {
this.startHour = startHour;
}
public void setEndHour(int endHour) {
this.endHour = endHour;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
Subject subject = getSubject(request, response);
// Must be authenticated
if (!subject.isAuthenticated()) {
return false;
}
// Check time-based access
Calendar now = Calendar.getInstance();
int currentHour = now.get(Calendar.HOUR_OF_DAY);
boolean withinBusinessHours = currentHour >= startHour && currentHour < endHour;
// Admins can access anytime
if (subject.hasRole("admin")) {
return true;
}
// Regular users only during business hours
return withinBusinessHours;
}
}
// Usage
public void configureTimeBasedAccess() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
TimeBasedAccessFilter timeFilter = new TimeBasedAccessFilter();
timeFilter.setStartHour(8);
timeFilter.setEndHour(18);
manager.addFilter("businessHours", timeFilter);
// Restrict access to business systems during business hours
manager.createChain("/business/**", "authc, businessHours");
manager.createChain("/admin/**", "authc, roles[admin]"); // Admins can access anytime
}public void configureComplexAuthorization() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
// Configure multiple authorization filters
SslFilter sslFilter = new SslFilter();
HostFilter hostFilter = new HostFilter();
RolesAuthorizationFilter rolesFilter = new RolesAuthorizationFilter();
PermissionsAuthorizationFilter permsFilter = new PermissionsAuthorizationFilter();
manager.addFilter("ssl", sslFilter);
manager.addFilter("host", hostFilter);
manager.addFilter("roles", rolesFilter);
manager.addFilter("perms", permsFilter);
// Complex authorization chains
manager.createChain("/admin/system/**",
"ssl, host[127.0.0.1,192.168.1.0/24], authc, roles[admin], perms[system:admin]");
manager.createChain("/api/financial/**",
"ssl, authc, roles[finance,manager], perms[financial:read]");
manager.createChain("/reports/sensitive/**",
"ssl, authc, roles[admin,auditor], perms[report:sensitive]");
// Default chains
manager.createChain("/public/**", "anon");
manager.createChain("/**", "authc, roles[user]");
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-shiro--shiro-web