Весенняя безопасность: почему мы не можем получить доступ к параметрам полномочий 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.

Один и тот же ключ для другой сущности из-за реализации интерфейса.

Другие вопросы по тегам