-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Description
Expected Behavior
When using the @PreFilter and @PostFilter annotations with Kotlin's Collection and Map, the filtering logic should be applied as it is in Java code.
Current Behavior
Any Kotlin Collections and empty Maps throw an UnsupportedOperationException as these types in Kotlin are immutable, but the implementation of DefaultMethodSecurityExpressionHandler attempts to mutate their state.
Minimal reproducible example:
Context
For Collections, that happens in the following lines:
Lines 154 to 155 in 64e2a2f
| filterTarget.clear(); | |
| filterTarget.addAll(retain); |
For Mapss, the same happens in the following lines:
Lines 192 to 193 in 64e2a2f
| filterTarget.clear(); | |
| filterTarget.putAll(retain); |
This fact is also reflected in the javadoc:
Lines 115 to 117 in 64e2a2f
| * If a {@code Collection} or {@code Map} is used, the original instance will be | |
| * modified to contain the elements for which the permission expression evaluates to | |
| * {@code true}. For an array, a new array instance will be returned. |
Moreover, the official Spring Security documentation on Method Security, specifically the sections Filtering Method Parameters with @PreFilter and Filtering Method Results with @PostFilter clearly mention that "@PreFilter/@PostFilter is not yet supported for Kotlin-specific data types; for that reason, only Java snippets are shown".
How has this issue affected you?
It has prevented me from being able to use the @PreFilter and @PostFilter annotations in my Spring Boot projects written in Kotlin.
What other alternatives have you considered?
Writing my own implementation of the MethodSecurityExpressionHandler interface.
This works for my usecase, but I would like the whole Spring Security community to benefit and be able to use the @PreFilter/@PostFilter with Kotlin by default. Additionally, implementing this solution within my own codebase increases internal dependencies and liabilities.
What are you trying to accomplish?
Add first-party support for the Kotlin data types by making DefaultMethodSecurityExpressionHandler work with them.
Are you aware of any workarounds?
Using the mutable variants of Kotlin's read-only data types.
This does not work for my usecase as it undermines the benefits of Kotlin's (preferred) in-built immutable types.
Action Items
Proposed solution in the following pull request: