Spring 启动 2.x.x - @ConditionalOnExpression:表达式解析失败
Spring Boot 2.x.x - @ConditionalOnExpression: Expression parsing failed
我正在使用 Spring 启动 2.2.5.RELEASE
。在我的 application.properties
文件中,我具有以下属性:
security.basic.authorize-mode=authenticated
security.basic.enabled=true
由于 simplification of Spring Boot default security configuration、
,它们不再可自定义
我无法通过 application.properties
使用它。
我已经研究并尝试 使用注释 @ConditionalOnExpression
两个属性,例如:
@ConditionalOnExpression("${security.basic.enabled:true} && ${security.basic.authorize-mode:authenticated}")
按照同样的逻辑,这个 。
但这对我不起作用,因为我有 authenticated
而不是值 true/false
:
所以,我试着这样写:
@ConditionalOnExpression("${security.basic.enabled:true} && ${security.basic.authorize.mode}.equals('authenticated')")
它编译良好,但在 运行 程序之后,我收到错误:
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnExpressionCondition.evaluateExpression(OnExpressionCondition.java:60) ~[spring-boot-autoconfigure-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnExpressionCondition.getMatchOutcome(OnExpressionCondition.java:48) ~[spring-boot-autoconfigure-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.2.5.RELEASE.jar:2.2.5.RELEASE]
... 26 common frames omitted
Caused by: org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:135) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:61) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:33) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
我可以将 @ConditionalOnExpression
或 @ConditionalOnProperty
用于多个属性,而不仅仅是布尔值 true/false
吗?
更新:
我添加了单引号:
@ConditionalOnExpression("${security.basic.authorize.mode:'authenticated'} && ${security.basic.enabled:true}")
在这种情况下,我得到:
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Boolean] for value 'authenticated'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value 'authenticated'
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:70) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 36 common frames omitted
Caused by: java.lang.IllegalArgumentException: Invalid boolean value 'authenticated'
at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:63) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:31) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:385) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 38 common frames omitted
我还尝试使用 environment.getProperty()
作为 @ConditionalOnExpression
注释:
@ConditionalOnExpression("#{environment.getProperty('security.basic.authorize.mode') eq('authenticated') && environment.getProperty('security.basic.enabled') eq('true')}")
如 所述,我可以将 WebSecurityConfigurerAdapter
与经过身份验证的访问规则一起使用:
public class SpringSecurityConfiguration
extends WebSecurityConfigurerAdapter {
private final UserInfoDetailsService userInfoDetailsService;
public SpringSecurityConfiguration_Database(UserInfoDetailsService userInfoDetailsService) {
this.userInfoDetailsService = userInfoDetailsService;
}
@Override
protected void configure(
AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder
.userDetailsService(userInfoDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/user/**", "/h2-console")
.authenticated()
.and()
.httpBasic()
.realmName("...")
.and()
.csrf()
.disable();
}
}
我正在使用 Spring 启动 2.2.5.RELEASE
。在我的 application.properties
文件中,我具有以下属性:
security.basic.authorize-mode=authenticated
security.basic.enabled=true
由于 simplification of Spring Boot default security configuration、
,它们不再可自定义我无法通过 application.properties
使用它。
我已经研究并尝试 @ConditionalOnExpression
两个属性,例如:
@ConditionalOnExpression("${security.basic.enabled:true} && ${security.basic.authorize-mode:authenticated}")
按照同样的逻辑,这个 authenticated
而不是值 true/false
:
所以,我试着这样写:
@ConditionalOnExpression("${security.basic.enabled:true} && ${security.basic.authorize.mode}.equals('authenticated')")
它编译良好,但在 运行 程序之后,我收到错误:
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnExpressionCondition.evaluateExpression(OnExpressionCondition.java:60) ~[spring-boot-autoconfigure-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnExpressionCondition.getMatchOutcome(OnExpressionCondition.java:48) ~[spring-boot-autoconfigure-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.2.5.RELEASE.jar:2.2.5.RELEASE]
... 26 common frames omitted
Caused by: org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:135) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:61) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:33) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
我可以将 @ConditionalOnExpression
或 @ConditionalOnProperty
用于多个属性,而不仅仅是布尔值 true/false
吗?
更新: 我添加了单引号:
@ConditionalOnExpression("${security.basic.authorize.mode:'authenticated'} && ${security.basic.enabled:true}")
在这种情况下,我得到:
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Boolean] for value 'authenticated'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value 'authenticated'
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:70) ~[spring-expression-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 36 common frames omitted
Caused by: java.lang.IllegalArgumentException: Invalid boolean value 'authenticated'
at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:63) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:31) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:385) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 38 common frames omitted
我还尝试使用 environment.getProperty()
作为 @ConditionalOnExpression
注释:
@ConditionalOnExpression("#{environment.getProperty('security.basic.authorize.mode') eq('authenticated') && environment.getProperty('security.basic.enabled') eq('true')}")
如 WebSecurityConfigurerAdapter
与经过身份验证的访问规则一起使用:
public class SpringSecurityConfiguration
extends WebSecurityConfigurerAdapter {
private final UserInfoDetailsService userInfoDetailsService;
public SpringSecurityConfiguration_Database(UserInfoDetailsService userInfoDetailsService) {
this.userInfoDetailsService = userInfoDetailsService;
}
@Override
protected void configure(
AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder
.userDetailsService(userInfoDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/user/**", "/h2-console")
.authenticated()
.and()
.httpBasic()
.realmName("...")
.and()
.csrf()
.disable();
}
}