Spring Boot集成Swagger与JWT鉴权时 如何为特定API禁用Authorize按钮
解决Swagger全局JWT配置下的接口授权按钮差异化控制问题
问题核心本质
Postman调试完全正常,说明Spring Security本身的鉴权拦截逻辑是对的——公开的认证接口已经被正确放行,受保护的接口也能正常校验token。 现在的Swagger异常本质是Swagger的页面渲染逻辑和实际的业务鉴权逻辑是完全独立的两套规则:你现在的SwaggerConfig给所有接口统一绑定了全局JWT安全规则,不管这个接口实际要不要鉴权,渲染的时候都会在对应接口块上挂上Authorize授权标识,根本没法靠页面上的按钮单独关掉某个接口的授权入口。
单独为Authenticate接口隐藏授权按钮的调整方法
不需要依赖页面上的交互操作,直接修改SwaggerConfig的规则匹配范围,不让全局安全规则覆盖公开接口路径即可:
- 收窄全局匹配范围,排除认证接口路径
原来的配置大概率是这类无差别全匹配的逻辑:
改成用正则排除公开认证路径的匹配规则:.securityContexts(Collections.singletonList( SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.any()) .build() ))
调整后,.securityContexts(Collections.singletonList( SecurityContext.builder() .securityReferences(defaultAuth()) // 匹配除了/auth/开头的公开路径之外的所有受保护接口 .forPaths(PathSelectors.regex("^(?!/auth/).*$")) .build() ))/auth/**路径下的Authenticate接口不会关联任何JWT安全规则,自然就不会在接口块上展示Authorize按钮。 - 自定义标记注解做规则匹配
如果不想写复杂的正则表达式,可以自定义一个@EnableSwaggerAuth标记注解,打在需要鉴权的控制器上,Swagger配置只给带这个注解的接口绑定安全规则,没打注解的公开接口(比如AuthenticateController)就会自动跳过授权关联。
单控制器粒度的授权按钮控制实现
完全可以实现单控制器粒度的授权按钮控制,这也是Swagger原生支持的配置能力,比全局限定的方式灵活很多,常用的实现路径有两个:
- 按控制器路径拆分独立安全上下文
比如你现在有两个独立的控制器:- 公开的AuthenticateController,路径映射为
/auth/** - 受保护的HelloController,路径映射为
/hello/**
不需要写一条覆盖所有路径的全局规则,分别给两个路径范围配置独立的安全上下文即可:
- 匹配
/hello/**的上下文,关联之前定义的JWT Bearer授权规则 - 匹配
/auth/**的上下文,把安全引用列表设为空数组,不关联任何鉴权要求
后续新增控制器的时候,只要给对应路径加一条匹配规则就行,不会出现新接口默认被绑定全局授权的问题。
- 公开的AuthenticateController,路径映射为
- 用Swagger原生注解在控制器层覆盖规则
如果用的是SpringDoc或者新版本的Springfox,直接在不需要鉴权的控制器类上加@SecurityRequirements注解,把安全要求设为空,就能单独覆盖全局的安全规则,不需要调整全局的匹配范围配置。
常见配置坑提醒
很多人改完配置发现Swagger还是显示授权按钮,大概率是没调整全局securityReferences的匹配范围:如果你给JWT授权引用设的是PathSelectors.any()的全局匹配,哪怕在单个接口上加了跳过授权的注解,Swagger也会优先走全局规则,给所有接口都挂上授权标识。调整的时候一定要把全局规则的匹配范围收窄,不要无差别覆盖所有路径。
内容的提问来源于stack exchange,提问作者shivaraj malannavar
相关产品推荐
相关产品推荐

