我想知道为什么 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.Boolean
java.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
: 既不是配置问题,也不是注入问题。我检查了这些值是否正确注入。