【发布时间】:2013-11-19 02:59:42
【问题描述】:
我想知道为什么 spring 不直接评估所有表达式,因为它们是从属性文件注入到 @PreAuthorize(...) 注释中的。我认为 spring 不会评估某些字符,例如 '('、')'、''' 等,或者它会在属性文件中的注入值之上添加特殊字符。为了澄清起见,让我们考虑以下示例。
@PreAuthorize("hasRole('ROLE_ADMIN')")
上面的表达式是正常的,并且工作正常。假设属性文件的值如下。
role1=ROLE_ADMIN
role2='ROLE_ADMIN'
role3=hasRole('ROLE_ADMIN')
让我们从属性文件中注入
role1并将其传递给@PreAuthorize("hasRole(${role1})"),它工作正常。在评估hasRole(...)表达式的正常方式中,角色名称必须在单引号下,即'ROLE_ADMIN'。但在这里它适用于 ROLE_ADMIN。令人惊讶!。如果我们将属性文件中的
role2注入@PreAuthorize("hasRole(${role2})"),它会返回拒绝访问。这意味着它已被评估,但我们可以意识到传递给表达式的值不是“'ROLE_ADMIN'”。因此,如果角色名称在单引号下,则拒绝访问。另一个惊喜!-
如果我们尝试将属性文件中的
role3注入@PreAuthorize("${role3}"),它也不会被评估。 例外:-
java.lang.IllegalArgumentException: Failed to evaluate expression 'role3'根本原因: org.springframework.expression.spel.SpelEvaluationException: EL1001E:(pos 0): Type conversion problem, cannot convert from java.lang.String to java.lang.Booleanjava.lang.IllegalArgumentException: Invalid boolean value 'hasRole('ROLE_ADMIN')'
-
我的结论:
从上面的(1)和(2),我们可以意识到一件事。也就是说,似乎注入的值在传递给 @PreAuthorize(...) 注释时放在单引号 (' ') 下。如果此陈述不正确,则 (1) 和 (2) 将不起作用。这只是我的结论!
当我们来到 (3) 时,情况似乎类似于 (1) 和 (2)。文件中的值为“hasRole('ROLE_ADMIN')”。正确注入此值后,如果在传递给@PreAuthorize(...) 时添加单引号,它将像@PreAuthorize("'hasRole('ROLE_ADMIN')'")。所以“'hasRole('ROLE_ADMIN')'”是一个字符串而不是一个布尔值。它只是我的嫌疑人。
问题:
你认为我的结论是正确的吗?如果没有,你能指出我是否有遗漏的东西吗?或者,如果您有其他解决方案可以通过从属性文件中注入值来实现@PreAuthorize(...),请提供给我。
提前谢谢你!
Note:既不是配置问题,也不是注入问题。我检查了这些值是否正确注入。
【问题讨论】:
标签: java spring spring-security annotations spring-el