其他分享
首页 > 其他分享> > 从属性文件注入时,Spring可以评估SpEL表达式中的所有字符/表达式吗?

从属性文件注入时,Spring可以评估SpEL表达式中的所有字符/表达式吗?

作者:互联网

我不知道为什么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一起使用.奇怪!.
>如果我们将角色2从属性文件注入到@PreAuthorize(“ hasRole(${role2})”)),它将返回拒绝访问.那意味着它被评估了,但是我们可以意识到传递给表达式的值不是“’ROLE_ADMIN’”.因此,如果角色名称用单引号引起来,则拒绝访问.另一个惊喜!
>如果我们尝试将属性文件中的role3注入@PreAuthorize(“ ${role3}”),则不会对其进行评估.
例外情况:

> java.lang.IllegalArgumentException:无法用根源评估表达式’role3’:
> org.springframework.expression.spel.SpelEvaluationException:EL1001E:(pos 0):类型转换问题,无法从java.lang.String转换为java.lang.Boolean
> java.lang.IllegalArgumentException:无效的布尔值’hasRole(‘ROLE_ADMIN’)’

我的结论是:

从上面的(1)和(2),我们可以实现一件事.也就是说,当注入的值传递给@PreAuthorize(…)批注时,似乎将其置于单引号(”)下.如果此语句不正确,则(1)和(2)将不起作用.这只是我的结论!

当我们谈到(3)时,情况似乎类似于(1)和(2).文件中的值为“ hasRole(‘ROLE_ADMIN’)”.正确注入此值后,如果在传递给@PreAuthorize(…)时添加单引号,则将类似于@PreAuthorize(“’hasRole(‘ROLE_ADMIN’)’”).因此,“’hasRole(‘ROLE_ADMIN’)’”是一个字符串,而不是布尔值.这只是我的怀疑.

题:

您认为我的结论正确吗?如果不是,您能指出我是否错过了什么吗?如果您有其他解决方案可以通过从属性文件注入值来实现@PreAuthorize(…),请提供给我.

先感谢您!

注意:这既不是配置问题也不是注入问题.我检查了值是否正确注入.

解决方法:

答案的关键是如何在SpEL中表示字符串文字.以下是有效的:

> SpEL中的字符串文字用单引号引起来,例如“ Hello”是SpEL字符串文字.
>资源束中的所有值都将转换为String文字,这意味着:

>如果您从Java中的捆绑软件中获取HELLO,您将收到“ HELLO”字符串文字.
>如果您从SpEL中的捆绑软件中获取HELLO,您将收到’HELLO’字符串文字.

现在,让我们看一下上面的示例.

>在第一种情况下,资源束中有role1 = ROLE_ADMIN,这意味着在评估${role1}时将创建’ROLE_ADMIN’字符串文字.这将导致@PreAuthorize(“ hasRole(‘ROLE_ADMIN’)”)批注是完全有效的(如果定义了ROLE_ADMIN角色).这就是它起作用的原因,这并不奇怪.
>在第二种情况下,资源束中有role2 =’ROLE_ADMIN’,这意味着在评估${role2}时将创建一个”’ROLE_ADMIN”’字符串文字.请注意,通过放置两个字符将’符号转义.您收到“访问被拒绝”错误,仅是因为您没有“ ROLE_ADMIN”角色,而是ROLE_ADMIN(这是不同的).
>您的第三个猜测几乎是正确的.唯一您不正确的地方是注释看起来像在评估资源束中的#{role3}值.如前所述,在SpEL中,通过放置两个’字符来转义’.因此,注释看起来像@PreAuthorize(“’hasRole(”’ROLE_ADMIN”’)’”)).您完全正确的假设是这是一个字符串,而不是布尔表达式,这就是抛出IllegalArgumentException的原因.

标签:spring-security,annotations,spring-el,spring,java
来源: https://codeday.me/bug/20191122/2060498.html