PermissionEvaluator moves complex authorization rules out of long SpEL expressions and into a dedicated class. A document service can allow access when the caller is an administrator or the document owner. section 11.4
Implement the permission check around these pieces:
- Annotate the protected method with @PostAuthorize and call hasPermission(returnObject, 'ROLE_admin') when authorization depends on the returned object. section 11.4
- Implement the object-and-permission overload for checks that receive the target object directly. section 11.4
- Implement the identifier-and-type overload when the evaluator must load the target from its identifier. section 11.4
- Register the evaluator on DefaultMethodSecurityExpressionHandler so method-security expressions can invoke it. section 11.4
Owner-or-administrator document access
A DocumentsPermissionEvaluator compares the authenticated name with Document.owner and also checks for ROLE_admin. Natalie can read Emma’s document as an administrator; Emma receives 403 for Natalie’s document. section 11.4
Listing 11.15 Implementing the authorization rule
@Component
public class DocumentsPermissionEvaluator
implements PermissionEvaluator { #1
@Override
public boolean hasPermission(
Authentication authentication,
Object target,
Object permission) {
Document document = (Document) target; #2
String p = (String) permission; #3
boolean admin = #4
authentication.getAuthorities()
.stream()
.anyMatch(a -> a.getAuthority().equals(p));
return admin || #5
document.getOwner()
.equals(authentication.getName());
}
@Override
public boolean hasPermission(Authentication authentication,
Serializable targetId,
String targetType,
Object permission) {
return false; #6
}
}
Inspect the evaluator implementation that combines authority and ownership checks. section 11.4
Listing 11.16 Configuring the PermissionEvaluator in the configuration class
@Configuration
@EnableMethodSecurity
public class ProjectConfig {
private final DocumentsPermissionEvaluator evaluator;
// omitted constructor
@Bean #1
protected MethodSecurityExpressionHandler createExpressionHandler() {
var expressionHandler = #2
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(
evaluator); #3
return expressionHandler; #4
}
// Omitted definition of the UserDetailsService and PasswordEncoder beans
}
Inspect the method-security configuration that connects the evaluator to SpEL. section 11.4
