Я только что обновил свое приложение до 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();
}
}
Я не уверен, что так и должно быть, но я знаю, что это пока не работает;)
Может кто-нибудь помочь?