Skip to content

Returning a Mono root object from a custom EvaluationContextExtensionSupport does not work [DATACMNS-1365] #1801

@spring-projects-issues

Description

@spring-projects-issues

Gabor szabo opened DATACMNS-1365 and commented

Using Spring Boot 2.0.4.RELEASE, spring-boot-starter-webflux, spring-boot-starter-security and spring-boot-starter-data-mongodb-reactive, I tried to create a custom EvaluationContextExtensionSupport that returns a part of the Authentication object.

The class is the following:

public class PrincipalEvaluationContextExtensionSupport extends EvaluationContextExtensionSupport {
  @Override
    public String getExtensionId() {
    return "principal";
    }

  @Override
    public Mono<Principal> getRootObject() {

        return ReactiveSecurityContextHolder.getContext().map(SecurityContext::getAuthentication).map(Authentication::getPrincipal).map(principal -> (Principal) principal);

    }

}

This is a dummy ReactiveCrudRepository that would use my custom extension:

@Repository
 public interface ItemRepository extends ReactiveCrudRepository<Item, String> {
   @Query("{ email: ?#

{principal.email}

  }")
     Flux<Item> findByUser();
}

The Item class:

@Data
 @Document
 @NoArgsConstructor
 @AllArgsConstructor
 @RequiredArgsConstructor
 public class Item 

{       @Id       private String id;      @NotNull      @NonNull      private String description;      @NotNull      @NonNull      private String email;  }

Note that Principal is just a simple POJO. If I return a dummy Principal instance instead of a Mono<Principal>, everything works fine. However, with Mono, the following exception is thrown:

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'email' cannot be found on object of type 'org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider$EvaluationContextExtensionAdapter' - maybe not public or not valid?org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'email' cannot be found on object of type 'org.springframework.data.repository.query.ExtensionAwareEvaluationContextProvider$EvaluationContextExtensionAdapter' - maybe not public or not valid? at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:217) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:51) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:407) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:89) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:116) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:306) ~[spring-expression-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder.evaluateExpression(ExpressionEvaluatingParameterBinder.java:246) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder.getParameterValueForBinding(ExpressionEvaluatingParameterBinder.java:217) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder.replacePlaceholders(ExpressionEvaluatingParameterBinder.java:137) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.mongodb.repository.query.ExpressionEvaluatingParameterBinder.bind(ExpressionEvaluatingParameterBinder.java:107) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.mongodb.repository.query.ReactiveStringBasedMongoQuery.createQuery(ReactiveStringBasedMongoQuery.java:125) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.mongodb.repository.query.AbstractReactiveMongoQuery.execute(AbstractReactiveMongoQuery.java:108) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.mongodb.repository.query.AbstractReactiveMongoQuery.execute(AbstractReactiveMongoQuery.java:91) ~[spring-data-mongodb-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) ~[spring-data-commons-2.0.9.RELEASE.jar:2.0.9.RELEASE]
...

 

I'm not sure if it is a Spring Data Commons or a Spring Data MongoDB issue, or is it a feature request that is not supported yet?

Unfortunately I don't find a workaround. I cannot call block on the Mono because then Spring WebFlux throws an exception, but I cannot get the Authentication object synchronously.

Thanks for the help/guidelines


No further details from DATACMNS-1365

Metadata

Metadata

Assignees

Labels

status: supersededAn issue that has been superseded by anothertype: bugA general bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions