Package security

Class AbstractAccessCheckInterceptor

java.lang.Object
security.AbstractAccessCheckInterceptor
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
InMemoryAccessCheckInterceptor

public abstract class AbstractAccessCheckInterceptor extends Object implements Serializable
Abstract base class for security interceptors that enforce access control on methods annotated with AccessCheck.

How it works:

  1. Intercepts any method annotated with @AccessCheck
  2. Determines the resource identifier:
    • For callAccessPointMethod() on a BaseDyntabCdiBean (which is annotated with @AccessCheck): uses the bean's uniqueIdentifier (from the @DynTab annotation that matches this specific tab instance). This solves the problem of multiple @DynTab annotations on the same class with different securedResource values.
    • For other methods: uses the fully qualified method name (com.example.MyBean.myMethod)
  3. Calls isResourceSecured(String) — if not secured, allows access
  4. If secured, retrieves user roles from the session and calls hasPermission(String, Set)
  5. If denied and the method is callAccessPointMethod(), sets accessDenied=true on the bean and proceeds (the bean renders an "access denied" page instead of the main content)
  6. If denied and it's a regular method, shows a FacesMessage error and throws a RuntimeException

Two implementation strategies:

  1. Declarative (InMemory): Use InMemoryAccessCheckInterceptor, paired with InMemorySecuredResourceScanner. Access rules are declared directly in annotations (@DynTab(allowedRoles=...) and @AccessCheck(allowedRoles=...)). This is the default approach provided by the DynTabs library.
  2. DB-based: The developer creates a custom DBAccessCheckInterceptor extending this class, paired with a custom DBSecuredResourceScanner. The allowedRoles annotation attribute is ignored — roles are managed through an Admin UI and stored in the database.

User roles: By default, reads user roles from the session attribute "user_roles" (a Set<String>). Override getUserRoles() to customize.

IMPORTANT: Any interceptor applied to a ViewScoped or TabScoped CDI bean MUST implement Serializable, otherwise passivation will fail.

NOTE: CDI interceptors only intercept external method calls (via proxy). When a bean calls its own @AccessCheck method internally, the interceptor will NOT fire.

Author:
DynTabs
See Also:
  • Field Details

    • log

      protected static final org.slf4j.Logger log
  • Constructor Details

    • AbstractAccessCheckInterceptor

      public AbstractAccessCheckInterceptor()
  • Method Details

    • checkPermissions

      public Object checkPermissions(jakarta.interceptor.InvocationContext context) throws Exception
      Throws:
      Exception
    • getUserRoles

      protected Set<String> getUserRoles()
      Retrieves the current user's roles from the session.

      Default implementation reads the "user_roles" attribute from the JSF external context session map. Override to customize (e.g., read from a different session attribute, or from Jakarta Security).

      Returns:
      set of role names for the current user, or empty set if not available
    • isResourceSecured

      protected abstract boolean isResourceSecured(String resource)
      Checks whether the given resource is secured (requires access control).

      If this returns false, access is allowed without any role check.

      Parameters:
      resource - the resource identifier (uniqueIdentifier for tabs, or fully qualified method name)
      Returns:
      true if the resource is secured and requires permission check
    • hasPermission

      protected abstract boolean hasPermission(String resource, Set<String> userRoles)
      Checks whether the given user roles grant access to the specified resource.

      Called only if isResourceSecured(String) returned true.

      Parameters:
      resource - the resource identifier
      userRoles - the current user's roles
      Returns:
      true if access should be granted