Spring Boot中Springfox生成OAuth/token端点无效Swagger Schema问题
这个问题我之前在整合Springfox和Spring Security OAuth2时也碰到过——Springfox在扫描框架自带的/oauth/token端点时,错误地把Spring MVC内部用来接收请求参数的MultiValueMap<String, String> parameters对象直接映射成了Swagger参数,但完全没遵循Swagger 2.0的规范生成正确的Schema结构。
从你贴的swagger.json片段能看到,第二个参数只加了items字段,却缺少了Swagger参数必须的type(应该指定为array)、或者合法的schema/$ref属性,这就直接触发了第三方校验工具的报错。
给你两个靠谱的解决办法,按需选就行:
方法1:自定义Springfox插件修正端点参数
最彻底的方式是写一个Springfox插件,专门处理/oauth/token的POST请求,把错误生成的参数替换成符合OAuth2规范的标准参数。这样既保留了端点在Swagger中的展示,又能通过校验:
@Component public class OAuthTokenEndpointFixPlugin implements OperationBuilderPlugin { @Override public void apply(OperationContext context) { // 定位到/oauth/token的POST请求 if ("/oauth/token".equals(context.requestMappingPattern()) && "post".equalsIgnoreCase(context.httpMethod().name())) { // 清空错误生成的参数列表 context.operationBuilder().parameters(new ArrayList<>()); // 手动添加OAuth2 token请求的标准参数 context.operationBuilder() .parameter(new ParameterBuilder() .name("grant_type") .description("授权类型,例如password、client_credentials等") .modelRef(new ModelRef("string")) .parameterType("query") .required(true) .build()) .parameter(new ParameterBuilder() .name("client_id") .description("客户端ID") .modelRef(new ModelRef("string")) .parameterType("query") .required(true) .build()) .parameter(new ParameterBuilder() .name("client_secret") .description("客户端密钥") .modelRef(new ModelRef("string")) .parameterType("query") .required(false) .build()) .parameter(new ParameterBuilder() .name("username") .description("用户名(grant_type为password时必填)") .modelRef(new ModelRef("string")) .parameterType("query") .required(false) .build()) .parameter(new ParameterBuilder() .name("password") .description("密码(grant_type为password时必填)") .modelRef(new ModelRef("string")) .parameterType("query") .required(false) .build()) .parameter(new ParameterBuilder() .name("scope") .description("授权范围") .modelRef(new ModelRef("string")) .parameterType("query") .required(false) .build()); } } @Override public boolean supports(DocumentationType documentationType) { return DocumentationType.SWAGGER_2.equals(documentationType); } }
添加这个插件后,Springfox在生成Swagger文档时会自动修正/oauth/token的POST请求参数,完全符合规范。
方法2:临时规避(不推荐但快速)
如果只是想快速解决校验报错,也可以暂时把/oauth/token从Swagger扫描中排除,但这样就没法在API文档里展示这个端点了。修改你的Docket配置:
.paths(Predicates.not(PathSelectors.regex("/oauth/token")))
当然,这只是权宜之计,还是方法1更符合你的需求。
重启应用后,访问/api/v2/api-docs获取最新的swagger.json,你会看到/oauth/token的POST请求参数已经变成了标准的OAuth2参数,第三方校验工具的报错也会消失。
内容的提问来源于stack exchange,提问作者Dmitrii Borovoi

