A powerful and flexible open-source Java security framework providing authentication, authorization, session management, and cryptographic services
—
Apache Shiro's authorization framework provides comprehensive access control through role-based and permission-based authorization. It supports wildcard permissions, annotation-driven security, and flexible authorization policies that can be applied at both programmatic and declarative levels.
The primary interface for performing authorization operations.
/**
* An Authorizer performs authorization (access control) operations for any given Subject.
*/
public interface Authorizer {
/**
* Returns true if the corresponding Subject is permitted to perform an action or access a resource.
* @param principals the application-specific subject/user identifier
* @param permission the permission being checked
* @return true if permitted, false otherwise
*/
boolean isPermitted(PrincipalCollection principals, String permission);
/**
* Returns true if the corresponding Subject is permitted to perform an action or access a resource.
* @param principals the application-specific subject/user identifier
* @param permission the permission being checked
* @return true if permitted, false otherwise
*/
boolean isPermitted(PrincipalCollection principals, Permission permission);
/**
* Returns true if the corresponding Subject has the specified role.
* @param principals the application-specific subject/user identifier
* @param roleIdentifier the application-specific role identifier
* @return true if the subject has the specified role, false otherwise
*/
boolean hasRole(PrincipalCollection principals, String roleIdentifier);
/**
* Ensures the corresponding Subject is permitted to perform an action or access a resource.
* @param principals the application-specific subject/user identifier
* @param permission the permission being checked
* @throws AuthorizationException if the subject is not permitted
*/
void checkPermission(PrincipalCollection principals, String permission) throws AuthorizationException;
/**
* Ensures the corresponding Subject is permitted to perform an action or access a resource.
* @param principals the application-specific subject/user identifier
* @param permission the permission being checked
* @throws AuthorizationException if the subject is not permitted
*/
void checkPermission(PrincipalCollection principals, Permission permission) throws AuthorizationException;
/**
* Ensures the corresponding Subject has the specified role.
* @param principals the application-specific subject/user identifier
* @param roleIdentifier the application-specific role identifier
* @throws AuthorizationException if the subject does not have the specified role
*/
void checkRole(PrincipalCollection principals, String roleIdentifier) throws AuthorizationException;
}
/**
* Authorizer implementation that uses configured realms to perform authorization operations.
*/
public class ModularRealmAuthorizer implements Authorizer, PermissionResolverAware, RolePermissionResolverAware {
/**
* Sets the realms used by this Authorizer.
* @param realms the realms used for authorization operations
*/
public void setRealms(Collection<Realm> realms);
/**
* Returns the realms used by this Authorizer.
* @return the realms used for authorization operations
*/
public Collection<Realm> getRealms();
/**
* Sets the PermissionResolver used to resolve strings into Permission instances.
* @param permissionResolver the PermissionResolver to use
*/
public void setPermissionResolver(PermissionResolver permissionResolver);
/**
* Sets the RolePermissionResolver used to resolve role strings into Permission instances.
* @param rolePermissionResolver the RolePermissionResolver to use
*/
public void setRolePermissionResolver(RolePermissionResolver rolePermissionResolver);
}Authorization information provided by realms.
/**
* AuthorizationInfo represents a single Subject's stored authorization data (roles, permissions, etc).
*/
public interface AuthorizationInfo extends Serializable {
/**
* Returns the names of all roles that are granted to the corresponding Subject.
* @return the names of all roles that are granted to the corresponding Subject
*/
Collection<String> getRoles();
/**
* Returns the names of all string-based permissions granted to the corresponding Subject.
* @return the names of all string-based permissions granted to the corresponding Subject
*/
Collection<String> getStringPermissions();
/**
* Returns all object-based permissions granted to the corresponding Subject.
* @return all object-based permissions granted to the corresponding Subject
*/
Collection<Permission> getObjectPermissions();
}
/**
* Simple implementation of the AuthorizationInfo interface.
*/
public class SimpleAuthorizationInfo implements AuthorizationInfo {
public SimpleAuthorizationInfo();
/**
* Constructor that accepts a set of roles.
* @param roles the set of roles granted to the corresponding Subject
*/
public SimpleAuthorizationInfo(Set<String> roles);
/**
* Adds (assigns) a role to the corresponding Subject.
* @param role the role to add
*/
public void addRole(String role);
/**
* Adds (assigns) multiple roles to the corresponding Subject.
* @param roles the roles to add
*/
public void addRoles(Collection<String> roles);
/**
* Adds (assigns) a permission to the corresponding Subject.
* @param permission the permission to add
*/
public void addStringPermission(String permission);
/**
* Adds (assigns) multiple string-based permissions to the corresponding Subject.
* @param permissions the permissions to add
*/
public void addStringPermissions(Collection<String> permissions);
/**
* Adds (assigns) an object permission to the corresponding Subject.
* @param permission the permission to add
*/
public void addObjectPermission(Permission permission);
/**
* Adds (assigns) multiple object permissions to the corresponding Subject.
* @param permissions the permissions to add
*/
public void addObjectPermissions(Collection<Permission> permissions);
}Apache Shiro's flexible permission system supporting various permission models.
/**
* A Permission represents the ability to perform an action or access a resource.
*/
public interface Permission {
/**
* Returns true if this current instance implies all the functionality and/or resource access described by the specified Permission argument.
* @param p the permission to check for behavior/functionality comparison
* @return true if this current instance implies all the functionality and/or resource access described by the specified Permission argument
*/
boolean implies(Permission p);
}
/**
* A very powerful and flexible permission implementation based on Ant-style path expressions.
*/
public class WildcardPermission implements Permission {
/**
* Constructor accepting a wildcard string.
* @param wildcardString the wildcard string to parse
*/
public WildcardPermission(String wildcardString);
/**
* Constructor accepting a wildcard string and case sensitivity flag.
* @param wildcardString the wildcard string to parse
* @param caseSensitive whether the permission should be case sensitive
*/
public WildcardPermission(String wildcardString, boolean caseSensitive);
public boolean implies(Permission p);
public String toString();
}
/**
* An all-allowing permission that grants access to everything.
*/
public class AllPermission implements Permission {
public AllPermission();
public boolean implies(Permission p);
}
/**
* Interface for components that can resolve permission strings into Permission objects.
*/
public interface PermissionResolver {
/**
* Resolves a permission string into a Permission object.
* @param permissionString the permission string to resolve
* @return a Permission object representing the specified string
*/
Permission resolvePermission(String permissionString);
}
/**
* Default implementation that creates WildcardPermission instances from permission strings.
*/
public class WildcardPermissionResolver implements PermissionResolver {
public WildcardPermissionResolver();
public Permission resolvePermission(String permissionString);
}
/**
* Interface implemented by components that need to be aware of the system's PermissionResolver.
*/
public interface PermissionResolverAware {
/**
* Sets the PermissionResolver to be used by this component.
* @param pr the PermissionResolver to use
*/
void setPermissionResolver(PermissionResolver pr);
}Usage Examples:
// Wildcard permissions
WildcardPermission userPerm = new WildcardPermission("user:*");
WildcardPermission specificPerm = new WildcardPermission("user:create:123");
// Check if broader permission implies more specific one
if (userPerm.implies(specificPerm)) {
System.out.println("User permission allows creation of user 123");
}
// Permission examples:
// "file:read" - read any file
// "file:read,write" - read and write any file
// "file:read:*" - read any file
// "file:read:/documents/*" - read any file in documents directory
// "file:read,write:/documents/private" - read and write specific fileSystem for mapping roles to permissions dynamically.
/**
* Interface for resolving permissions assigned to roles.
*/
public interface RolePermissionResolver {
/**
* Returns the permissions that the specified role implies.
* @param roleString the application-specific role identifier
* @return the permissions that the specified role implies
*/
Collection<Permission> resolvePermissionsInRole(String roleString);
}
/**
* Interface implemented by components that need to be aware of the system's RolePermissionResolver.
*/
public interface RolePermissionResolverAware {
/**
* Sets the RolePermissionResolver to be used by this component.
* @param rpr the RolePermissionResolver to use
*/
void setRolePermissionResolver(RolePermissionResolver rpr);
}Declarative authorization through method-level annotations.
/**
* Annotation requiring the current user to be authenticated (not anonymous) in order to access the annotated class/instance/method.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresAuthentication {
}
/**
* Annotation requiring the current user to be a "user", meaning they are either remembered from a previous session or authenticated in the current session.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresUser {
}
/**
* Annotation requiring the current user to be a "guest", meaning they are not authenticated or remembered from a previous session.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresGuest {
}
/**
* Annotation requiring the current Subject to have one or more roles in order to execute the annotated method.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRoles {
/**
* The role identifiers required for the method execution to continue.
* @return the role identifiers required for the method execution to continue
*/
String[] value();
/**
* The logical operation for combining the required roles.
* @return the logical operation for combining the required roles
*/
Logical logical() default Logical.AND;
}
/**
* Annotation requiring the current Subject to have one or more permissions in order to execute the annotated method.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {
/**
* The permission strings required for the method execution to continue.
* @return the permission strings required for the method execution to continue
*/
String[] value();
/**
* The logical operation for combining the required permissions.
* @return the logical operation for combining the required permissions
*/
Logical logical() default Logical.AND;
}
/**
* Enumeration for specifying logical operations when combining multiple authorization criteria.
*/
public enum Logical {
AND, OR
}Usage Examples:
public class UserService {
@RequiresAuthentication
public void updateProfile(User user) {
// Method requires authenticated user
}
@RequiresRoles("admin")
public void deleteUser(String userId) {
// Method requires admin role
}
@RequiresRoles(value = {"admin", "manager"}, logical = Logical.OR)
public void viewReports() {
// Method requires admin OR manager role
}
@RequiresPermissions("user:create")
public void createUser(User user) {
// Method requires specific permission
}
@RequiresPermissions(value = {"user:read", "user:write"}, logical = Logical.AND)
public void editUser(String userId, User updates) {
// Method requires both read and write permissions
}
@RequiresGuest
public void showRegistrationPage() {
// Method only for unauthenticated users
}
}Aspect-oriented programming support for method-level authorization.
/**
* Base class for method interceptors that perform authorization checks.
*/
public abstract class AuthorizingMethodInterceptor extends AnnotationMethodInterceptor {
/**
* Performs the authorization check before method execution.
* @param methodInvocation the method invocation being intercepted
* @throws AuthorizationException if authorization fails
*/
protected abstract void assertAuthorized(MethodInvocation methodInvocation) throws AuthorizationException;
}
/**
* Method interceptor that asserts the calling Subject is authenticated before allowing access.
*/
public class AuthenticatedMethodInterceptor extends AuthorizingMethodInterceptor {
public AuthenticatedMethodInterceptor();
protected void assertAuthorized(MethodInvocation mi) throws AuthorizationException;
}
/**
* Method interceptor that asserts the calling Subject has the required roles before allowing access.
*/
public class RoleMethodInterceptor extends AuthorizingMethodInterceptor {
public RoleMethodInterceptor();
protected void assertAuthorized(MethodInvocation mi) throws AuthorizationException;
}
/**
* Method interceptor that asserts the calling Subject has the required permissions before allowing access.
*/
public class PermissionMethodInterceptor extends AuthorizingMethodInterceptor {
public PermissionMethodInterceptor();
protected void assertAuthorized(MethodInvocation mi) throws AuthorizationException;
}/**
* Base exception for all authorization-related problems.
*/
public class AuthorizationException extends ShiroException {
public AuthorizationException();
public AuthorizationException(String message);
public AuthorizationException(Throwable cause);
public AuthorizationException(String message, Throwable cause);
}
/**
* Exception thrown when a Subject is not authorized to perform a particular action.
*/
public class UnauthorizedException extends AuthorizationException {
public UnauthorizedException();
public UnauthorizedException(String message);
public UnauthorizedException(Throwable cause);
public UnauthorizedException(String message, Throwable cause);
}
/**
* Exception thrown when a Subject is required to be authenticated but is not.
*/
public class UnauthenticatedException extends AuthorizationException {
public UnauthenticatedException();
public UnauthenticatedException(String message);
public UnauthenticatedException(Throwable cause);
public UnauthenticatedException(String message, Throwable cause);
}public interface MethodInvocation {
Object proceed() throws Throwable;
Method getMethod();
Object[] getArguments();
Object getThis();
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-shiro--shiro-core