如何基于用户角色控制SwaggerUI中可访问的OpenAPI分组
实现SpringFox OpenAPI分组的角色级可见性控制
要让只有ADMIN角色能在Swagger UI中看到"My Group 1"分组,核心思路是动态过滤Swagger UI展示的资源列表,同时配合Spring Security限制该分组API文档的直接访问权限,具体实现如下:
1. 自定义Swagger资源提供者,按角色过滤分组
Swagger UI通过获取/v3/api-docs/{group}的资源列表渲染分组,我们可以自定义SwaggerResourcesProvider实现,根据当前用户角色移除非ADMIN用户的目标分组:
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.SwaggerResourcesProvider; import java.util.List; import java.util.stream.Collectors; @Component public class RoleBasedSwaggerResourcesProvider implements SwaggerResourcesProvider { private final SwaggerResourcesProvider defaultProvider; // 注入SpringFox默认的资源提供者 public RoleBasedSwaggerResourcesProvider(SwaggerResourcesProvider defaultProvider) { this.defaultProvider = defaultProvider; } @Override public List<SwaggerResource> get() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); List<SwaggerResource> allResources = defaultProvider.get(); // 非ADMIN用户过滤掉"My Group 1"分组 if (auth != null && !auth.getAuthorities().stream() .anyMatch(authItem -> authItem.getAuthority().equals("ROLE_ADMIN"))) { return allResources.stream() .filter(resource -> !"My Group 1".equals(resource.getName())) .collect(Collectors.toList()); } return allResources; } }
2. 配置Spring Security,限制分组文档的访问权限
除了隐藏分组,还要防止普通用户直接访问该分组的API文档端点,在Security配置中添加规则:
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 允许所有用户访问Swagger UI基础资源 .antMatchers("/swagger-ui/**", "/v3/api-docs").permitAll() // 仅ADMIN能访问"My Group 1"的API文档 .antMatchers("/v3/api-docs/My Group 1").hasRole("ADMIN") // 同时限制该分组对应接口的访问权限 .antMatchers("/api/group1/**").hasRole("ADMIN") // 其他接口按实际需求配置 .anyRequest().authenticated() .and() .formLogin(); // 根据你的认证方式调整,比如JWT、OAuth2等 } }
关键注意事项
- 确保分组名称完全匹配:
GroupedOpenApi中定义的group("My Group 1")要和过滤逻辑中的名称一致,否则无法生效。 - 认证上下文有效性:如果使用JWT等无状态认证,要确保
SecurityContextHolder能正确获取当前用户的Authentication对象。 - SpringFox版本适配:上述代码基于SpringFox 3.x,若使用旧版本(如2.x),需调整相关类路径(比如
SwaggerResourcesProvider的包路径不同)。
内容的提问来源于stack exchange,提问作者Mar Ek
相关产品推荐
相关产品推荐

