Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Custom Permission Evaluator in Spring Boot
📖 Scenario: You are building a secure Spring Boot web application where users have different roles and permissions. You want to control access to certain methods based on custom permission logic.For example, only users with the right permission can edit or delete resources.
🎯 Goal: Create a custom permission evaluator class that checks if a user has a specific permission on a target domain object.Integrate this evaluator with Spring Security so it can be used in method security annotations.
📋 What You'll Learn
Create a class implementing PermissionEvaluator
Add a configuration bean to register the custom permission evaluator
Implement the hasPermission method with custom logic
Use the custom permission evaluator in a method security annotation
💡 Why This Matters
🌍 Real World
Custom permission evaluators allow fine-grained access control in enterprise applications, enabling security decisions based on complex business rules.
💼 Career
Understanding and implementing custom permission evaluators is important for backend developers working with Spring Security to secure APIs and services.
Progress0 / 4 steps
1
Create the CustomPermissionEvaluator class
Create a class called CustomPermissionEvaluator that implements PermissionEvaluator. Override both hasPermission methods with empty bodies returning false.
Spring Boot
Hint
Implement the PermissionEvaluator interface and override both hasPermission methods with default false returns.
2
Add a configuration bean to register the custom permission evaluator
Create a Spring configuration class called SecurityConfig with a @Bean method named permissionEvaluator that returns a new instance of CustomPermissionEvaluator.
Spring Boot
Hint
Use @Configuration and @Bean annotations to register your custom permission evaluator.
3
Implement custom logic in hasPermission method
Modify the hasPermission(Authentication authentication, Object targetDomainObject, Object permission) method in CustomPermissionEvaluator to return true if the authentication has a granted authority matching the permission string. Otherwise, return false.
Spring Boot
Hint
Check if any authority in authentication.getAuthorities() matches the permission string.
4
Use the custom permission evaluator in method security
In a service class called DocumentService, add a method editDocument that takes a String documentId. Annotate this method with @PreAuthorize("hasPermission(#documentId, 'Document', 'EDIT')") to use the custom permission evaluator.
Spring Boot
Hint
Use @PreAuthorize with the hasPermission expression referencing #documentId, target type 'Document', and permission 'EDIT'.
Practice
(1/5)
1. What is the main purpose of a Custom PermissionEvaluator in Spring Boot security?
easy
A. To handle database connections securely
B. To replace the entire Spring Security framework
C. To define custom rules for checking user permissions in a reusable way
D. To manage user sessions automatically
Solution
Step 1: Understand the role of PermissionEvaluator
The PermissionEvaluator interface allows defining custom logic to check if a user has permission to perform an action.
Step 2: Identify the purpose of custom implementation
Implementing a custom PermissionEvaluator lets you write your own rules that can be reused across your application for security checks.
Final Answer:
To define custom rules for checking user permissions in a reusable way -> Option C
PermissionEvaluator has two methods: one with targetDomainObject and one with targetId and targetType.
Step 2: Identify the method for domain object permission check
The method hasPermission(Authentication authentication, Object targetDomainObject, Object permission) is used to check permissions on a domain object.
Final Answer:
hasPermission(Authentication authentication, Object targetDomainObject, Object permission) -> Option B
Quick Check:
Domain object permission method = hasPermission with targetDomainObject [OK]
Hint: Override hasPermission with targetDomainObject for object checks [OK]
Common Mistakes:
Choosing methods not in PermissionEvaluator interface
Confusing method parameters
Using method names that don't exist
3. Given this custom PermissionEvaluator method snippet:
public boolean hasPermission(Authentication auth, Object target, Object perm) {
if (auth == null || target == null || !(perm instanceof String)) {
return false;
}
String permission = (String) perm;
User user = (User) auth.getPrincipal();
return user.getRoles().contains(permission);
}
What will be the result if auth is null?
medium
A. Returns false immediately
B. Throws NullPointerException
C. Returns true by default
D. Ignores null and continues
Solution
Step 1: Analyze the null check at method start
The method checks if auth is null and returns false immediately if so.
Step 2: Understand the flow when auth is null
Since auth == null triggers return false, no further code runs and no exception occurs.
Final Answer:
Returns false immediately -> Option A
Quick Check:
Null auth returns false immediately [OK]
Hint: Null checks return false early to avoid exceptions [OK]
Common Mistakes:
Assuming NullPointerException will be thrown
Thinking it returns true by default
Ignoring the null check logic
4. You wrote this custom PermissionEvaluator method:
public boolean hasPermission(Authentication auth, Object target, Object perm) {
String permission = (String) perm;
User user = (User) auth.getPrincipal();
return user.getRoles().contains(permission);
}
What is the main problem with this code?
medium
A. It should return true by default
B. Casting perm to String is unnecessary
C. User roles cannot be checked this way
D. It lacks null checks and may throw NullPointerException
Solution
Step 1: Check for missing null validations
The method does not check if auth, perm, or auth.getPrincipal() are null before casting or calling methods.
Step 2: Understand consequences of missing null checks
If any are null, the code will throw NullPointerException at runtime.
Final Answer:
It lacks null checks and may throw NullPointerException -> Option D
Quick Check:
Missing null checks cause runtime exceptions [OK]
Hint: Always add null checks before casting or method calls [OK]
Common Mistakes:
Ignoring null safety
Thinking casting is always safe
Assuming roles check is invalid
5. You want to create a custom PermissionEvaluator that allows a user to edit a document only if they have the "EDITOR" role and the document status is "DRAFT". Which code snippet correctly implements this logic inside hasPermission?
hard
A. if (auth == null || target == null) return false;
User user = (User) auth.getPrincipal();
Document doc = (Document) target;
return user.getRoles().contains("EDITOR") && "DRAFT".equals(doc.getStatus());
B. User user = (User) auth.getPrincipal();
Document doc = (Document) target;
return user.getRoles().contains("EDITOR") || doc.getStatus().equals("DRAFT");
C. if (auth == null) return true;
Document doc = (Document) target;
return doc.getStatus() == "DRAFT";
D. User user = (User) auth.getPrincipal();
return user.getRoles().contains("EDITOR");
Solution
Step 1: Check for null authentication and target
Security checks should return false if authentication or target is null to avoid errors.
Step 2: Verify user role and document status conditions
The user must have "EDITOR" role and the document status must be exactly "DRAFT" for permission to be granted.
Step 3: Confirm correct logical operator usage
Both conditions must be true, so use logical AND (&&), not OR (||).
Final Answer:
if (auth == null || target == null) return false;
User user = (User) auth.getPrincipal();
Document doc = (Document) target;
return user.getRoles().contains("EDITOR") && "DRAFT".equals(doc.getStatus()); -> Option A
Quick Check:
Check nulls + role AND status = correct logic [OK]
Hint: Use && to combine role and status checks with null safety [OK]