Skip to main content

6.4 Role-Based & Method Security

← Back to Chapter 6: Spring Security & Authentication

Role-Based Access Control (RBAC) and fine-grained method security guarantee that users execute only operations permitted by their specific roles and privileges.


1. Roles vs Authorities​

In Spring Security, the difference between a Role and an Authority is a matter of prefix:

  • Authority (Privilege/Permission): A granular capability string, such as user:read, order:delete, invoice:export.
  • Role: A coarse-grained bundle of privileges. By convention, Spring Security prefixes roles with ROLE_ (e.g., ROLE_ADMIN, ROLE_MANAGER).
// Checking a Role:
.hasRole("ADMIN") // Spring internally checks for authority "ROLE_ADMIN"!

// Checking a Granular Authority:
.hasAuthority("order:write") // Exact string match without prefix

2. Declarative Method-Level Security​

Enable method-level security in your configuration using @EnableMethodSecurity:

@Configuration
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig {}

Powerful SpEL (Spring Expression Language) Annotations:​

@Service
public class OrderService {

// 1. Role-based check
@PreAuthorize("hasRole('ADMIN')")
public void deleteOrder(UUID orderId) { ... }

// 2. Multi-role check
@PreAuthorize("hasAnyRole('MANAGER', 'SUPERVISOR')")
public void approveRefund(UUID orderId) { ... }

// 3. Authority-based check
@PreAuthorize("hasAuthority('reports:export')")
public byte[] exportMonthlyReport() { ... }

// 4. Fine-grained ownership check: User can only access their OWN data!
@PreAuthorize("hasRole('ADMIN') or #username == authentication.name")
public UserProfile getProfile(String username) { ... }

// 5. PostAuthorize: Inspect method return object before delivering to caller!
@PostAuthorize("returnObject.ownerId == authentication.principal.id")
public OrderDetails getOrderDetails(UUID orderId) { ... }
}

3. Filtering Collections with @PreFilter & @PostFilter​

  • @PostFilter("filterObject.owner == authentication.name"): Filters out elements from a returned List that do not belong to the calling user.
  • @PreFilter: Filters elements inside a collection parameter before the method executes.