Skip to main content

SpEL Expressions

Open in ChatGPT

Spring Expression Language (SpEL) provides a declarative way to define authorization rules directly in annotations. The @RouteAccess annotation evaluates SpEL expressions using Spring Security's built-in authorization functions.

Spring Security only

SpEL expressions are available only when using the Spring integration.

Basic usage

The @RouteAccess annotation accepts a SpEL expression that evaluates to a boolean:

@Route("/admin/dashboard")
@RouteAccess("hasRole('ADMIN')")
public class AdminDashboardView extends Composite<Div> {
// Only users with ROLE_ADMIN authority can access
}

If the expression evaluates to true, access is granted. If false, the user is redirected to the access denied page.

Built-in security functions

Spring Security provides the following authorization functions through SecurityExpressionRoot:

FunctionParametersDescriptionExample
hasRoleString roleChecks if user has the specified role (automatically prefixes with ROLE_)hasRole('ADMIN') matches ROLE_ADMIN
hasAnyRoleString... rolesChecks if user has any of the specified roleshasAnyRole('ADMIN', 'MANAGER')
hasAuthorityString authorityChecks if user has the exact authority stringhasAuthority('REPORTS:READ')
hasAnyAuthorityString... authoritiesChecks if user has any of the specified authoritieshasAnyAuthority('REPORTS:READ', 'REPORTS:WRITE')
isAuthenticatedNoneReturns true if user is authenticatedisAuthenticated()

Examples

// Role check
@Route("/admin")
@RouteAccess("hasRole('ADMIN')")
public class AdminView extends Composite<Div> { }

// Multiple roles
@Route("/staff")
@RouteAccess("hasAnyRole('ADMIN', 'MANAGER', 'SUPERVISOR')")
public class StaffView extends Composite<Div> { }

// Authority check
@Route("/reports")
@RouteAccess("hasAuthority('REPORTS:READ')")
public class ReportsView extends Composite<Div> { }

// Require authentication
@Route("/profile")
@RouteAccess("isAuthenticated()")
public class ProfileView extends Composite<Div> { }

Combining conditions

Use boolean operators (and, or, !) to create complex authorization rules:

// Both conditions required
@Route("/moderator/reports")
@RouteAccess("hasRole('MODERATOR') and hasAuthority('REPORTS:VIEW')")
public class ModeratorReportsView extends Composite<Div> { }

// Either condition grants access
@Route("/support")
@RouteAccess("hasRole('ADMIN') or hasRole('SUPPORT')")
public class SupportView extends Composite<Div> { }

// Negation
@Route("/trial/features")
@RouteAccess("isAuthenticated() and !hasAuthority('PREMIUM')")
public class TrialFeaturesView extends Composite<Div> { }

// Complex multi-line expression
@Route("/reports/advanced")
@RouteAccess("""
hasRole('ADMIN') or
(hasRole('ANALYST') and hasAuthority('REPORTS:ADVANCED'))
""")
public class AdvancedReportsView extends Composite<Div> { }

Combining with other annotations

@RouteAccess works alongside standard security annotations. Evaluators run in priority order:

@Route("/team/admin")
@RolesAllowed("USER")
@RouteAccess("hasAuthority('TEAM:ADMIN')")
public class TeamAdminView extends Composite<Div> {
// Must have USER role AND TEAM:ADMIN authority
}

Evaluation order:

  1. @RolesAllowed evaluator (priority 5) verifies USER role
  2. If passed, @RouteAccess evaluator (priority 6) evaluates SpEL expression
  3. If passed, custom evaluators run (priority 10+)

Custom error codes

Provide meaningful error codes for access denials:

@Route("/premium/features")
@RouteAccess(
value = "hasAuthority('PREMIUM')",
code = "PREMIUM_SUBSCRIPTION_REQUIRED"
)
public class PremiumFeaturesView extends Composite<Div> { }

The code parameter identifies the denial reason when the expression evaluates to false.

Available variables

SpEL expressions have access to these variables in the evaluation context:

VariableTypeDescription
authenticationAuthenticationSpring Security authentication object
principalObjectThe authenticated principal (usually UserDetails)
routeClassClass<? extends Component>The route component class being accessed
contextNavigationContextwebforJ navigation context
securityContextRouteSecurityContextwebforJ route security context

Example using variables:

@Route("/admin")
@RouteAccess("authentication.name == 'superadmin'")
public class SuperAdminView extends Composite<Div> { }

When to use SpEL VS custom evaluators

Use @RouteAccess SpEL when:

  • Authorization is based purely on roles or authorities
  • Combining built-in security functions with boolean logic
  • Route-specific rules that don't require reuse

Use custom evaluators when:

  • Authorization depends on route parameters (ownership checks)
  • Complex business logic requiring Spring service integration
  • Reusable authorization patterns across multiple routes
  • Custom annotations that document the authorization intent

See the Custom Evaluators guide for implementing advanced authorization scenarios.