Describe the bug When I define method to provide currently authenticated user within repository, I get NullPointerException.
EL1022E: The function 'isAuthenticated' mapped to an object of type 'class org.springframework.security.access.expression.SecurityExpressionRoot' which cannot be invoked
org.springframework.expression.spel.SpelEvaluationException: EL1022E: The function 'isAuthenticated' mapped to an object of type 'class org.springframework.security.access.expression.SecurityExpressionRoot' which cannot be invoked
...
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.security.authentication.AuthenticationTrustResolver.isAnonymous(org.springframework.security.core.Authentication)" because "this.trustResolver" is null
According to the docs you can use all of the Common Security Expressions within the Query.
To Reproduce
Use isAuthenticated(), or isAnonymous() inside @Query, i.e.:
@Query("SELECT u FROM User u WHERE u.username = :#{authentication.name} AND 1=:#{isAuthenticated()? 1:0}")
Optional<User> findCurrentUser();
You can run tests from sample repository. Tested with Spring Boot 2.6.7 and 2.7.0-RC1
Expected behavior No NPE exception
Sample https://github.com/slawekludwiczak/spring-data-security-bug
Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.
Comment From: sjohnr
Hi @slawekludwiczak, thanks for the report and the helpful sample!
I tried this out and can confirm what you're seeing. It seems to be caused by the SecurityEvaluationContextExtension:
https://github.com/spring-projects/spring-security/blob/f34ea188e29cafd6805236de21314905f1c03e0e/data/src/main/java/org/springframework/security/data/repository/query/SecurityEvaluationContextExtension.java#L109-L110
This instance of SecurityExpressionRoot doesn't ever seem to get a trustResolver. It seems this may have been a problem since this integration was introduced. Perhaps @rwinch could weigh in on context of this issue?
I'm not sure the changes needed in the repository, but I wonder if this could be worked around in the meantime by using a @PostFilter annotation? It may not be supported with Optional, and require returning a Collection of some kind instead.
Comment From: evgeniycheban
@sjohnr I'd like to work on this.
I looked over the code and it's also missing roleHierarchy and permissionEvaluator.
I think we should add these fields to the SecurityEvaluationContextExtension and provide setter methods to override defaults.
Comment From: sjohnr
Thanks @evgeniycheban, you are more than welcome to take this on!
Comment From: evgeniycheban
@sjohnr I've opened a PR ready for review.
Comment From: evgeniycheban
@sjohnr Do we need to include this fix to 5.7.x? I created my branch against 5.8.x.
Comment From: sjohnr
@evgeniycheban I think any new APIs would probably not go in 5.7. I think I could take care of backporting to 5.7 without trouble, so you don't need to worry about it. I'll review your PR in the next day or two. Thanks so much!