Restricting service-layer methods to specific roles is done by enabling method security and applying @PreAuthorize (or @Secured) annotations directly on the methods that require protection, so the check runs regardless of the calling path.
Key Points: • @EnableGlobalMethodSecurity(prePostEnabled = true) (or @EnableMethodSecurity in newer Spring Security) turns on annotation processing for method rules. • @PreAuthorize("hasRole('ADMIN')") blocks the method call up front if the current user lacks the role. • SpEL expressions in @PreAuthorize can also reference method parameters for object-level checks, e.g. hasRole('ADMIN') or #userId == principal.id. • Unauthorized calls throw AccessDeniedException, which a global exception handler can translate into a 403 response. • This approach protects the method even when called internally, not just when hit through a REST endpoint.
Example: An adminOnlyMethod() in a service class is annotated with @PreAuthorize("hasRole('ADMIN')") so that even if a developer later adds a new controller calling it, the role check is enforced automatically.
Code Example:
@Service
public class ReportService {
@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyMethod() {
// logic for admin only
}
}Interview Tip: A concise interview answer is:
"I'd enable method security with @EnableGlobalMethodSecurity(prePostEnabled = true), then annotate the sensitive service methods with @PreAuthorize using role expressions like hasRole('ADMIN'). That keeps the check enforced at the method itself, so it applies no matter which controller or internal code path calls it."