Authorization and Method Security Questions
What is the difference between hasRole and hasAuthority?
| Expression | Checks for authority | Typical use |
|---|---|---|
hasRole("ADMIN") | ROLE_ADMIN (prefix added for you) | coarse roles: USER, ADMIN |
hasAuthority("ROLE_ADMIN") | ROLE_ADMIN (exact string) | same check, written in full |
hasAuthority("product:write") | product:write | fine-grained permissions, OAuth2 scopes (SCOPE_read) |
A role is just an authority whose name starts with ROLE_. A common bug: storing ADMIN in the database but checking hasRole("ADMIN"), which looks for ROLE_ADMIN.
How do you enable method-level security?
@Configuration
@EnableMethodSecurity // prePostEnabled = true by default
public class MethodSecurityConfig { }
@Service
public class OrderService {
@PreAuthorize("hasRole('ADMIN') or #userId == authentication.name")
public List<Order> ordersOf(String userId) { ... }
@PostAuthorize("returnObject.owner == authentication.name")
public Order findOrder(Long id) { ... }
}securedEnabled = true turns on @Secured and jsr250Enabled = true turns on @RolesAllowed.
What is the difference between @PreAuthorize, @PostAuthorize, @PreFilter and @PostFilter?
@PreAuthorize: checks before the method runs (most common).@PostAuthorize: runs the method, then checks the return value (returnObject); the method has already executed.@PreFilter: removes elements from a collection argument that fail the expression (filterObject).@PostFilter: removes elements from the returned collection. Filtering in the database query is usually faster.
Why does @PreAuthorize sometimes not work?
- Self-invocation: method security uses Spring AOP proxies, so calling an annotated method from another method in the same class skips the check.
- The method is
privateor the class is not a Spring bean (created withnew). @EnableMethodSecurityis missing.- Role/prefix mismatch (
ADMINvsROLE_ADMIN).
URL-based rules or method security: which one should you use?
Use both. URL rules in the SecurityFilterChain are a coarse first gate (public vs logged-in vs admin areas). Method security sits on the service layer, close to the business rule, and can check ownership ("only the order owner can cancel it") using method arguments, which URL patterns cannot express. Method security also protects code reached from non-HTTP entry points like Kafka listeners or schedulers.
What is a role hierarchy?
@Bean
static RoleHierarchy roleHierarchy() {
return RoleHierarchyImpl.fromHierarchy("""
ROLE_ADMIN > ROLE_MANAGER
ROLE_MANAGER > ROLE_USER
""");
}With this bean, an ADMIN automatically passes hasRole("MANAGER") and hasRole("USER") checks, so you do not have to give every user all lower roles.