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 returnedListthat do not belong to the calling user.@PreFilter: Filters elements inside a collection parameter before the method executes.