Skip to content
๐Ÿ‡ช๐Ÿ‡บ Made in the European Union ยท Independently built ยท Released under EUPL 1.2
Architecture

Architecture

Module Structure

ModuleArtifactDescription
security-coresecurity-coreGeneric, framework-neutral security concepts and decision logic
security-vaadinsecurity-vaadinVaadin Flow adapter โ€” view and navigation security
security-restsecurity-restFramework-light REST adapter โ€” request and handler security
demo-vaadindemo-vaadinVaadin reference implementation (WAR)
demo-restdemo-restRunnable REST reference: JDK-only HTTP server + CLI client

Dependency Rules

security-core    -> (no project deps)
security-vaadin  -> security-core
security-rest    -> security-core
demo-vaadin      -> security-core, security-vaadin
demo-rest        -> security-core, security-rest

security-core has no Vaadin, Servlet, or REST-framework dependencies. security-vaadin and security-rest never depend on each other.

Core rule

Library modules do not define project-specific permissions. Concrete roles, permissions, and business operations belong to consuming applications or demo modules.

security-core provides generic types such as SecuritySubject, RoleName, PermissionName, AccessContext, AuthorizationDecision, evaluator contracts, plus the reusable building blocks listed below.

security-vaadin maps security decisions to Vaadin navigation behavior. It owns Vaadin session access through VaadinSessionSubjectStore, login redirection, access-denied rerouting, and BeforeEnterListener integration.

security-rest maps semantic authorization decisions to REST behavior. It uses minimal abstractions (RestRequest, RestResponse, RestHandler, BodyRestRequest) and does not pull in Spring Security, Jakarta Security, OAuth2/OIDC, or a web framework.

Decision Model

The library uses two decision types:

TypeModulePurpose
AuthorizationDecisionsecurity-coreAdapter-neutral: Granted / Unauthenticated / Forbidden
AccessDecisionsecurity-coreVaadin-oriented (legacy, kept for backward compatibility)

Adapters map these to framework-specific behavior:

  • security-vaadin โ†’ navigation: continue, reroute to login, or reroute to error.
  • security-rest โ†’ HTTP status: 200/handler, 401, or 403.

Annotation-Driven Protection

SecurityAnnotationScanner scans classes, methods, or any AnnotatedElement for restriction annotations meta-annotated with @SecurityAnnotation. Both adapters use the same scanner.

Generic annotations (in security-core):

  • @RequiresRole({"ROLE_ADMIN"}) โ†’ RequiresRoleEvaluator
  • @RequiresPermission("document:delete") โ†’ RequiresPermissionEvaluator
  • @ProtectedBy(...) โ†’ ProtectedByEvaluator

Project-specific annotations are encouraged for Vaadin views (e.g. @VisibleFor).

Reusable security building blocks

TypeModule / packagePurpose
PermissionGuardsecurity-core/.../authorization/apiStateless hasPermission / requirePermission (and role variants) on any HasPermissions/HasRoles. Throws AccessDeniedException.
StaticRolePermissionMappingโ€ฆ/api/permissionsImmutable role โ†’ permissions map with a builder.
RolePermissionResolverโ€ฆ/api/permissionsMerges permissions across multiple roles.
SecuredOperationDescriptor, SecuredOperationRegistry, OperationVisibilityServiceโ€ฆ/api/operationsGeneric operation discovery with subject-aware filtering. Adapter metadata (HTTP method, path, view class) goes into the descriptor’s attributes.
BootstrapConfigurationLoader, BootstrapStatussecurity-core/.../bootstrapCentralised sysprop+env+default loading with TTL parsing; leak-safe status snapshot.
RestHeaders, BearerTokenExtractorsecurity-restCase-insensitive header lookup and Bearer-token parsing.
RestAuthenticationFiltersecurity-rest401-only filter for authenticated-only endpoints.
BodyRestRequestsecurity-restBody-capable RestRequest. Avoids concrete-class casts in handlers.
BootstrapRestStatusMappersecurity-restInitialAdminCreationResult โ†’ HTTP status code + stable error code.

Stable vs. Experimental API

Stable: role-based access, REST adapter contracts, SecuritySubject, AccessContext, AuthorizationDecision, scanner.

Experimental (marked with @ExperimentalSecurityApi): permission-based access types โ€” PermissionBasedAccessEvaluator, PermissionName, HasPermissions, PermissionAuthorizationService. May change in incompatible ways in future releases.

Project-specific permissions live in applications

Library modules contain no concrete business permissions. Examples like document:read belong in demo-rest. Real applications define their own catalog (e.g. shortlink:create, audit:read) inside the consuming project.