Spring Security配置client_credentials授权拼写错误却正常工作的原因
核心原因
这个反常现象本质是Spring Security OAuth2客户端的默认配置逻辑,和你对接的授权服务器的认证要求不匹配导致的:
- 当你配置正确的
client_credentials授权类型时,Spring Security会加载该模式的默认客户端认证规则:自动将client-id和client-secret编码后放到请求的Authorization: Basic请求头中传递给授权服务器,不会把这两个参数放到POST请求体里。你抛出的invalid_client错误,就是因为你对接的外部授权服务器不支持通过Basic请求头传递客户端凭证,要求必须将client_id、client_secret作为表单参数放在请求体中提交,自然会判定客户端认证失败。 - 当你把授权类型错拼为
client_credentals时,Spring Security无法匹配到内置的标准client_credentials授权类型处理器,就不会加载对应的默认Basic认证逻辑,退回到通用的OAuth2令牌请求处理流程:这时候它不会自动添加Basic请求头,反而会把客户端ID、密钥都作为application/x-www-form-urlencoded格式的表单参数放到请求体里提交,刚好命中了目标授权服务器要求的认证方式,所以请求反而成功了。
正确修复方式
不需要靠拼写错误碰运气,只要显式指定客户端认证方式为表单传参即可,不需要改授权类型的正确拼写,在原有配置里补一行配置就行:
spring: security: oauth2: client: registration: AuthProvider: authorization-grant-type: client_credentials # 显式指定将客户端凭证放到请求体表单中传递,而非默认的Basic请求头 client-authentication-method: client_secret_post client-id: ***** client-secret: ***** scope: resource.READ,resource.WRITE provider: AuthProvider: token-uri: ******
补充说明:OAuth2规范本身就定义了多种客户端认证方式,Spring Security给client_credentials模式默认选的是Basic头传递的方式,但不少第三方开放平台、自研授权服务器只支持表单参数传递凭证,这是这类集成里非常常见的坑。你也可以抓包对比两种配置下发出的令牌请求,能很直观看到请求头、请求体的差异。
内容的提问来源于stack exchange,提问作者Anime
相关产品推荐
相关产品推荐

