Master Spring Security Method-Level Authorization with @PreAuthorize
This tutorial walks through enabling Spring Security method-level protection in a Spring Boot 2.7.16 project, covering @EnableGlobalMethodSecurity, role and authority checks, custom PermissionEvaluator, parameter access, custom annotations, and bean‑based permission rules with practical code examples.
Environment: SpringBoot 2.7.16
1. Introduction
Spring Security is a powerful, highly customizable authentication and access‑control framework for protecting Spring‑based applications. It offers authentication, authorization, session management, and supports various authentication methods such as form login and HTTP basic authentication. This article builds on a previous guide and demonstrates method‑level permission control using annotations like @PreAuthorize and @PostAuthorize .
2. Practical Example
2.1 Prepare the Environment
Enable method security in your configuration:
<code>@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
// TODO
}
</code>2.2 Role‑Based Access Control
Define a simple controller:
<code>@RestController
@RequestMapping("/users")
public class UserController {
public Object index(Long id) {
return "index";
}
}
</code>Restrict access to users with the ADMIN role:
<code>@PreAuthorize("hasRole('ADMIN')")
public Object index(Long id) { }
</code>Allow any of several roles:
<code>@PreAuthorize("hasAnyRole('ADMIN', 'MGR', ...)")
public Object index(Long id) { }
</code>2.3 Authority‑Based Access Control
Use hasAuthority to check a specific authority (no ROLE_ prefix is added):
<code>@PreAuthorize("hasAuthority('read')")
public Object index(Long id) { }
</code>hasAnyAuthority works similarly for multiple authorities.
2.4 Permission Evaluation
For fine‑grained checks, implement a custom PermissionEvaluator :
<code>@Bean
PermissionEvaluator permissionEvaluator() {
return new PermissionEvaluator() {
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
return false;
}
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
return authentication.getAuthorities().stream()
.filter(grant -> grant.getAuthority().equals(permission))
.findFirst().isPresent();
}
};
}
</code>After registering, you can use hasPermission in expressions.
2.5 Custom Domain Objects
Define a method that supplies a domain value for permission checks:
<code>public class UserController {
public String getName() { return "admin"; }
@PreAuthorize("hasPermission(this.getName(), 'read')")
public Object index(Long id) { return "index"; }
}
</code>Inside PermissionEvaluator , the second argument receives the value returned by this.getName() .
Example output from the custom evaluator:
2.6 Accessing Method Parameters
Method arguments are added to the SpEL context and can be accessed with #parameterName :
<code>@PreAuthorize("hasPermission(#id, 'read')")
public Object index(Long id) { }
</code>Alternatively, use indexed names:
<code>@PreAuthorize("hasPermission(#p0, 'read')")
@PreAuthorize("hasPermission(#a0, 'read')")
</code>2.7 Custom Parameter Names
Define a custom name with @P :
<code>@PreAuthorize("#p == 888")
public Object index(@P("p") Long id) { }
</code>2.8 Bean‑Based Permission Rules
Create a bean that contains custom logic:
<code>@Component("pp")
public class PackPermission {
public boolean hasPerm(String authority) {
return "admin".equals(authority);
}
}
</code>Use the bean in an expression:
<code>@PreAuthorize("@pp.hasPerm('admin1')")
public Object index(@P("p") Long id) { }
</code>The article demonstrates the full range of Spring Security method‑level authorization techniques, from basic role checks to custom permission evaluators and bean‑based rules.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.