spring security:为啥我们不能在@PreAuthorize 中访问 Hibernate 实体参数?

Posted

技术标签:

【中文标题】spring security:为啥我们不能在@PreAuthorize 中访问 Hibernate 实体参数?【英文标题】:spring security : Why can't we access Hibernate entitiy parameters in @PreAuthorize?spring security:为什么我们不能在@PreAuthorize 中访问 Hibernate 实体参数? 【发布时间】:2012-06-01 19:21:40 【问题描述】:

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

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

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

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

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

我真的不明白为什么 SPEL 解析器会认为 user 字段为空

【问题讨论】:

【参考方案1】:

您可以使用调试器检查 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() 方法中真正发生的事情,因为在 Spring 中非常清楚地实现了方法参数到 SPEL 变量的转换。

【讨论】:

谢谢你。事实证明,我在接口声明中的方法参数中的变量名与我实际实现的方法中的名称不同...... Spring 正在寻找后者名称【参考方案2】:

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

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

如果你使用

【讨论】:

谢谢,在方法签名中添加 @Param 注释对我有用。【参考方案3】:

您可以查看LazyParamAwareEvaluationContext,在loadArgsAsVariables() 方法中,版本3.1.0。

不同Entity的key相同,因为实现了接口。

【讨论】:

【参考方案4】:

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

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();

【讨论】:

以上是关于spring security:为啥我们不能在@PreAuthorize 中访问 Hibernate 实体参数?的主要内容,如果未能解决你的问题,请参考以下文章

元标记中带有令牌的 CSRF 保护 - 为啥不能被盗?

Spring security @EnableOAuth2Sso - 我们不能跳过开发环境的自签名 ssl 连接

为啥 Spring Security 使用默认的预认证检查?

为啥 Spring Security 身份验证会导致 CORS 错误

为啥 Spring Security getAuthentication() 在服务器上返回 null

为啥 Spring boot Security Basic Authentication 慢?