Spring Boot升级至2.7.4后OAuth2 Scope含空格引发非法参数异常
问题:Spring Boot 2.7.4(Java 17)升级后OAuth2 Scope含空格抛出IllegalArgumentException
问题场景
将应用从Java 8升级至Java 17,同步升级Spring Boot到2.7.4版本后,在设置access token时抛出非法参数异常。相同配置文件在Java 8环境下可正常运行,调试发现新版本Spring Boot无法解析Scope中的ASCII空格,旧版本则可正常处理。
异常信息如下:
java.lang.IllegalArgumentException: scope "audience:server:client_id:ADD_00000 AAA:drr:BADAM.SS_" contains invalid characters at org.springframework.util.Assert.isTrue(Assert.java:121) at org.springframework.security.oauth2.client.registration.ClientRegistration$Builder.validateScopes(ClientRegistration.java:706) at org.springframework.security.oauth2.client.registration.ClientRegistration$Builder.build(ClientRegistration.java:625) at com.restclient.oauth2.SpringSecurityRequestInterceptor.createClientRegistration(SpringSecurityRequestInterceptor.java:165) at com.restclient.oauth2.SpringSecurityRequestInterceptor.<init>(SpringSecurityRequestInterceptor.java:59) at com.restclient.oauth2.OAuth2RequestInterceptor.<init>(OAuth2RequestInterceptor.java:38) at com.restclient.feign.FeignRestClientBuilder.setTokenAuthentication(FeignRestClientBuilder.java:156) at com.restclient.RestClientHolder.configureBuilder(RestClientHolder.java:275) at com.restclient.RestClientHolder.getBuilder(RestClientHolder.java:313) at com.restclient.RestClientHolder.getService(RestClientHolder.java:319) at com.restclient.RestHelper.getService(RestHelper.java:34) at com.restclient.RestHelper.getService(RestHelper.java:80)
原因分析
Spring Security OAuth2在2.x版本(对应Spring Boot 2.7+)中收紧了Scope的字符校验规则。查看ClientRegistration.Builder.validateScopes方法实现,新版本会严格校验Scope字符是否符合RFC 6749规范,空格属于非法字符;而旧版本校验逻辑相对宽松,允许空格存在。
解决方案
方案1:替换Scope中的空格为合法字符
将Scope里的ASCII空格替换为URL编码的%20,或使用Token Master支持的其他分隔符(如下划线_、连字符-)。例如原Scope:
audience:server:client_id:ADD_00000 AAA:drr:BADAM.SS_
修改为:
audience:server:client_id:ADD_00000%20AAA:drr:BADAM.SS_
或:
audience:server:client_id:ADD_00000_AAA:drr:BADAM.SS_
需确认Token Master端能正确识别替换后的Scope格式。
方案2:自定义Scope校验逻辑(谨慎使用)
如果业务必须保留空格,可通过自定义ClientRegistration.Builder覆盖默认校验逻辑:
- 创建自定义Builder类,重写
validateScopes方法,移除空格校验; - 构建
ClientRegistration时使用自定义Builder替代默认实现。
示例代码片段:
public class CustomClientRegistrationBuilder extends ClientRegistration.Builder { public CustomClientRegistrationBuilder(String registrationId, String clientAuthenticationMethod, String authorizationGrantType, String redirectUri) { super(registrationId, clientAuthenticationMethod, authorizationGrantType, redirectUri); } @Override protected void validateScopes() { // 自定义校验逻辑,仅校验空值,允许空格 if (getScopes() != null) { for (String scope : getScopes()) { Assert.hasText(scope, "scope cannot be empty"); } } } }
构建ClientRegistration时使用该Builder:
ClientRegistration registration = new CustomClientRegistrationBuilder(...) .clientId("your-client-id") .scope("audience:server:client_id:ADD_00000 AAA:drr:BADAM.SS_") // 其他配置项 .build();
内容的提问来源于stack exchange,提问作者Sajit Gangadharan
相关产品推荐
相关产品推荐

