4

我有以下我正在应用@PreAuthorize 的接口方法:

@PreAuthorize("doSomething(#user.id)")
void something(User user, List<User> accessList);

其中User是一个Hibernate 实体对象。它给了我一个错误:

org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 13): 在 org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:204) 的 null 上找不到字段或属性“id”

参数不可能user为空,好像我删除了注释,并在实现此接口方法的方法中检查用户的值,那里存在一个有效的User对象。此外,就在调用此方法之前,我已确保正确构造了用户对象。

我真的无法弄清楚为什么userSPEL 解析器会将该字段视为 null

4

4 回答 4

2

您可以在Object lookupVariable(String name)方法中使用调试器检查MethodSecurityEvaluationContext中发生了什么:

    @Override
    public Object lookupVariable(String name) {
    Object variable = super.lookupVariable(name);

    if (variable != null) {
        return variable;
    }

    if (!argumentsAdded) {
        addArgumentsAsVariables();
        argumentsAdded = true;
    }

因此,您可以看到addArgumentsAsVariables()方法中真正发生的事情,因为在 Spring 中非常清楚地实现了方法参数到 SPEL 变量的转换。

于 2012-05-26T18:28:55.133 回答
1

Spring Security 现在对这个问题有了更好的答案:

http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#access-control-using-preauthorize-and-postauthorize

基本上,如果您使用的是<JDK 8,则可以使用@P 注释或@Param 注释。

于 2014-10-08T21:09:38.083 回答
0

您可以检查LazyParamAwareEvaluationContext内部loadArgsAsVariables()方法,版本 3.1.0。

由于实现接口,不同实体的相同键。

于 2012-08-24T07:33:27.093 回答
0

我需要为此添加一些内容,因为标题表明我们无法访问休眠属性。

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();
}
于 2014-10-30T09:19:16.027 回答