Весенняя безопасность: почему мы не можем получить доступ к параметрам полномочий Hibernate в @PreAuthorize?
У меня есть следующий метод интерфейса, к которому я применяю @PreAuthoriz
е:
@PreAuthorize("doSomething(#user.id)")
void something(User user, List<User> accessList);
где User
является объектом Hibernate. Это дает мне ошибку:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: (pos 13): Поле или свойство 'id' не может быть найдено в null в org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:204)
Там нет никакого способа, что user
Параметр имеет значение null, как будто я удаляю аннотацию и проверяю значение пользователя в методе, реализующем этот метод интерфейса, существует действительный User
объект присутствует там. Кроме того, непосредственно перед вызовом этого метода я убедился, что пользовательский объект построен правильно.
Я действительно не могу понять, почему user
поле будет считаться нулевым анализатором SPEL
4 ответа
С помощью отладчика вы можете проверить, что происходит в MethodSecurityEvaluationContext, внутри метода Object lookupVariable(String name):
@Override
public Object lookupVariable(String name) {
Object variable = super.lookupVariable(name);
if (variable != null) {
return variable;
}
if (!argumentsAdded) {
addArgumentsAsVariables();
argumentsAdded = true;
}
и поэтому вы можете увидеть, что на самом деле происходит в методе addArgumentsAsVariables(), поскольку преобразование аргументов метода в переменные SPEL очень четко реализовано в Spring.
У Spring Security есть лучший ответ на эту проблему:
http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/
По сути, вы можете использовать аннотацию @P или аннотацию @Param, если вы используете
Мне нужно что-то добавить к этому, так как заголовок указывает, что мы не можем получить доступ к свойствам гибернации.
Существует две редакции hasPermission: загруженный объект и сериализованный объект. Вот код из тестового примера:
@PreAuthorize("isAuthenticated() and hasPermission(#organization, 'edit')")
public long protectedMethod(Organization organization)
{
return organization.getId();
}
И для последнего здесь мы видим, что мы можем повлиять на доступ к id-идентификатору организации (которая является спящим объектом):
@PreAuthorize("isAuthenticated() and hasPermission(#organization.getId(), 'organization', 'edit')")
public long protectedMethodSerializableEdtion(Organization organization)
{
return organization.getId();
}
Ты можешь проверить LazyParamAwareEvaluationContext
, внутри loadArgsAsVariables()
метод, версия 3.1.0.
Один и тот же ключ для другой сущности из-за реализации интерфейса.