JPA - findById с @PostFilter: цель фильтра должна быть коллекцией или типом массива, но была необязательной - PullRequest
0 голосов
/ 03 июля 2018

Я только что обновил свое приложение до Spring Boot 2.0.3.RELEASE и обнаружил, что мой SpEL в @PostFilter больше не работает:

@PreAuthorize("isFullyAuthenticated()")
@PostFilter("hasAuthority('ADMIN') or @companyService.isOwnerOfPerson(#id, principal)")
@Override
public Optional<Person> findById(@Param("id") String id);

Ошибка org.springframework.security.authentication.InternalAuthenticationServiceException: целевым объектом фильтра должен быть тип коллекции или массива, но он является необязательным [Person ...]

Я видел, что это обсуждается на https://jira.spring.io/browse/SPR-15878, но я пытался обойти и запустить: я расширил DefaultMethodSecurityExpressionHandler и переписал метод setReturnObject, как предложено в билете, указанном выше:

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {

    @Override
    public void setReturnObject(Object returnObject, EvaluationContext ctx) {
        if (returnObject instanceof Optional) {
            Optional<?> optional = (Optional<?>)returnObject;

            Object value = null;
            if (optional.isPresent()) {
                value = optional.get();
            }

            ((MethodSecurityExpressionOperations) ctx.getRootObject().getValue())
            .setReturnObject(value);
        } else {
            super.setReturnObject(returnObject, ctx);
        }
    }

}

Далее я настроил метод защиты следующим образом:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new CustomMethodSecurityExpressionHandler();
    }

}

Я не уверен, что так и должно быть, но я знаю, что это пока не работает;)

Может кто-нибудь помочь?

1 Ответ

0 голосов
/ 30 октября 2018

эта ошибка появляется, потому что @PostFilter работает только с коллекциями (или массивами) в качестве возвращаемых значений, в то время как findById возвращает необязательное только одно значение. Вы можете увидеть это в своем сообщении об исключении:

Цель фильтра должна быть коллекцией или типом массива

...