Authorization and Method Security Questions

What is the difference between hasRole and hasAuthority?

ExpressionChecks for authorityTypical 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:writefine-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 private or the class is not a Spring bean (created with new).
  • @EnableMethodSecurity is missing.
  • Role/prefix mismatch (ADMIN vs ROLE_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.