news 2026/9/7 3:12:37

SpringCloud 屏蔽个别用户访问全部接口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringCloud 屏蔽个别用户访问全部接口

目录

方案 1:SpringCloud Gateway 全局过滤器(推荐)

1)黑名单存储

2)自定义 GlobalFilter

动态拉黑(Redis 版本)

方案 2:如果没有网关,在微服务内部拦截 HandlerInterceptor

方案 3:AOP 切面拦截(不推荐)

重要细节

选型总结


需求:拦截指定 1~2 个用户,禁止访问项目所有接口。

区分:用户身份,不是客户端 IP;一般根据userId / token解析出来的用户ID做黑名单。

可选实现方案优先级(从推荐到简单粗暴):

  1. Gateway 全局过滤器(首选,网关层拦截,请求不转发到微服务)
  2. 微服务内部全局拦截器 HandlerInterceptor
  3. AOP 切面拦截所有 Controller
  4. Spring Security 过滤器链

最佳实践:放在Spring Cloud Gateway 网关做拦截,请求直接在网关拒绝,不打到后端业务服务,节省资源。

方案 1:SpringCloud Gateway 全局过滤器(推荐)

网关层,所有微服务请求统一在这里校验黑名单。

1)黑名单存储

少量用户,可以内存 Set;生产建议放 Redis,方便动态增删拉黑用户,不用重启网关。

java

// 内存黑名单,测试用 private final Set<String> blackUserIdSet = Set.of("10001","10086");

生产环境使用 RedisSet结构,key:black:user:list

2)自定义 GlobalFilter

网关拿到 token 解析出 userId(你的业务逻辑解析 token),判断是否在黑名单,命中直接返回 403。

java

import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.annotation.Order; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.charset.StandardCharsets; import java.util.Set; @Component @Order(Integer.MIN_VALUE) // 优先级最高,最先执行 public class UserBlackListGlobalFilter implements GlobalFilter { // 黑名单用户ID,少量用户可以内存存放;生产使用Redis private final Set<String> blackUserIdSet = Set.of("10001", "10086"); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); // 1. 从header获取token,根据你的业务解析token得到userId String token = request.getHeaders().getFirst("Authorization"); String userId = parseUserIdByToken(token); // 【需要你自己实现token解析逻辑】 // 2. 判断用户是否黑名单 if(userId != null && blackUserIdSet.contains(userId)){ ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.FORBIDDEN); response.getHeaders().setContentType(MediaType.APPLICATION_JSON); String respJson = "{\"code\":403,\"msg\":\"您已被禁止访问系统\",\"data\":null}"; DataBuffer buffer = response.bufferFactory().wrap(respJson.getBytes(StandardCharsets.UTF_8)); return response.writeWith(Flux.just(buffer)); } // 放行 return chain.filter(exchange); } /** * 解析token获取userId,示例占位,替换成你项目真实逻辑 */ private String parseUserIdByToken(String token){ if(token == null){ return null; } // return JwtUtil.getUserId(token); return null; } }

⚠️注意:Gateway 是 WebFlux 响应式环境,不能用 Servlet 相关 API。

动态拉黑(Redis 版本)

把黑名单放到 Redis,网关读取,支持运行时新增 / 删除黑名单用户,无需重启网关:

java

// 判断逻辑替换 String userId = parseUserIdByToken(token); if(userId != null && Boolean.TRUE.equals(redisTemplate.opsForSet().isMember("black:user:list", userId))){ // 返回403禁止访问 }

方案 2:如果没有网关,在微服务内部拦截 HandlerInterceptor

SpringMVC 环境,普通微服务,所有 Controller 接口拦截。

java

import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Set; @Component public class UserBlackInterceptor implements HandlerInterceptor { private final Set<String> blackUserIdSet = Set.of("10001","10086"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); String userId = parseTokenGetUserId(token); if(userId != null && blackUserIdSet.contains(userId)){ response.setStatus(403); response.setContentType("application/json;charset=utf‑8"); ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(response.getWriter(), Map.of("code",403,"msg","禁止访问")); return false; // false:拦截,不进入controller } return true; } private String parseTokenGetUserId(String token){ // 业务解析token return null; } }

注册拦截器:

java

@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private UserBlackInterceptor userBlackInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userBlackInterceptor) .addPathPatterns("/**"); // 拦截全部接口 } }

缺点:如果多微服务,每个服务都要配置拦截器;优先网关统一处理

方案 3:AOP 切面拦截(不推荐)

拦截 @Controller/@RestController 所有方法。

缺点:异常接口、过滤器、静态资源、response 直接输出场景 AOP 切不到,有漏网接口。只适合临时应急。

重要细节

  1. 白名单:内部健康检查接口 /actuator/网关过滤器中可以放过健康检查,避免拉黑逻辑把服务监控搞挂:

java

String path = request.getPath().value(); if(path.startsWith("/actuator/")){ return chain.filter(exchange); }
  1. 区分:拉黑用户 IDvs 拉黑 IP。你的场景是用户,不要用 IP。
  2. token 为空(未登录请求)直接放行,黑名单只针对登录用户。
  3. 少量黑名单用户内存 Set 够用;后续黑名单变多一定要迁移 Redis,支持运营后台拉黑用户。

选型总结

方案适用场景优点缺点
Gateway 全局 FilterSpringCloud 网关架构✅请求在网关拦截,不转发后端,性能最好,统一管控需要网关服务
HandlerInterceptor无网关,微服务内部简单,SpringMVC 原生多微服务需要每个服务配置
AOP 切面临时快速实现编码简单存在部分接口拦截失效风险

如果你现在项目有 SpringCloud Gateway,直接用方案 1,这是生产标准做法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 3:11:24

流程即组织力:如何把个人能力沉淀为体系能力

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 3:09:19

myaifast-1804 AI Agent 选型 3 套组合 ROI 算账

myaifast-1804 AI Agent 选型实战&#xff1a;MCP / LangChain / 自研函数调用 3 套组合的真实 ROI 算账 90% 的团队选 Agent 框架是看 GitHub star 数——3 套组合&#xff08;MCPLangChain / LangChain 单用 / 自研&#xff09;的真实 ROI 算账告诉你 star 数最少的那个反而 …

作者头像 李华
网站建设 2026/9/7 3:08:18

游戏网络同步实战:用Yojimbo 1.11.0构建可靠UDP通信层

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华