Permission Expressions
| Expression | Description |
|---|---|
| permitAll() | Always returns true, granting access to all users, authenticated or not. |
| denyAll() | Always returns false, denying access to everyone. |
| isAnonymous() | Returns true if the current user is anonymous (not logged in). |
| isRememberMe() | Returns true if the user was authenticated via a "Remember-Me" token. |
| isAuthenticated() | Returns true if the user is authenticated, including via "Remember-Me". |
| isFullyAuthenticated() | Returns true if the user is authenticated via standard credentials (not anonymous or "Remember-Me"). |
| hasRole(String role) | Returns true if the user has the specified role. Note: Spring Security automatically prefixes the role name with "ROLE_". |
| hasAnyRole(String... roles) | Returns true if the user has any of the specified roles. |
| hasAuthority(String authority) | Returns true if the user has the specified authority. Unlike hasRole, no "ROLE_" prefix is added. |
| hasAnyAuthority(String... authorities) | Returns true if the user has any of the specified authorities. |
| hasIpAddress(String ipAddr) | Returns true if the request originates from the specified IP address or subnet. |
Example configuration:
securityConfig
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/users").hasAuthority("USER_MANAGE")
.antMatchers("/admin/roles").hasAnyRole("ROLE_ADMINISTRATOR", "ROLE_SUPERUSER")
.antMatchers(HttpMethod.GET, "/api/data")
.access("hasAuthority('DATA_READ') or hasRole('ROLE_ADMINISTRATOR')")
.anyRequest().authenticated();
Example user service configuration:
UserDetails user = new User(login, pwd,
AuthorityUtils.commaSeparatedStringToAuthorityList("USER_READ,DATA_MANAGE,ROLE_ADMINISTRATOR"));
Method-Level Authorization with Annotations
To enable method-level security, annotate your configuration class:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {
// ...
}
| Annotation | Description |
|---|---|
| @PreAuthorize | Performs a permission check before the method is invoked. Access is granted only if the expression evaluates to true. |
| @PostAuthorize | Performs a permission check after the method is invoked. If the expression evaluates to false, a 403 Forbidden error is thrown. The special variable returnObject can be used to inspect the method's return value. |
| @PreFilter | Filters the method's arguments before it is invoked. The special variable filterObject represents each element in a collection argument. |
| @PostFilter | Filters the method's return value. The special variable filterObject represents each element in the returned collection. |
Example usage:
@PreAuthorize("hasRole('ROLE_ADMINISTRATOR')")
@GetMapping("/secured")
public ResponseEntity<apiresponse> securedEndpoint() {
return ResponseEntity.ok(new ApiResponse("Access granted"));
}
@PostAuthorize("returnObject.status == 'SUCCESS'")
@GetMapping("/validate")
public ResponseEntity<apiresponse> validateEndpoint() {
return ResponseEntity.ok(new ApiResponse("SUCCESS"));
}
@PreFilter(filterTarget = "ids", value = "filterObject > 10")
@GetMapping("/filter-ids/{ids}")
public ResponseEntity<apiresponse> filterIds(@PathVariable List<integer> ids) {
return ResponseEntity.ok(new ApiResponse("Processed IDs: " + ids));
}
@PostFilter("filterObject > 20")
@GetMapping("/filter-results")
public List<integer> filterResults() {
List<integer> numbers = new ArrayList<>();
numbers.add(15);
numbers.add(25);
numbers.add(35);
return numbers;
}
</integer></integer></integer></apiresponse></apiresponse></apiresponse>
Note: Annotation-based security can be applied to both controller and service layers, whereas configuration-based security is typically limited to the controller layer.