ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

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

SpringCloud 屏蔽个别用户访问全部接口 目录方案 1SpringCloud Gateway 全局过滤器推荐1黑名单存储2自定义 GlobalFilter动态拉黑Redis 版本方案 2如果没有网关在微服务内部拦截 HandlerInterceptor方案 3AOP 切面拦截不推荐重要细节选型总结需求拦截指定 1~2 个用户禁止访问项目所有接口。区分用户身份不是客户端 IP一般根据userId / token解析出来的用户ID做黑名单。可选实现方案优先级从推荐到简单粗暴Gateway 全局过滤器首选网关层拦截请求不转发到微服务微服务内部全局拦截器 HandlerInterceptorAOP 切面拦截所有 ControllerSpring Security 过滤器链最佳实践放在Spring Cloud Gateway 网关做拦截请求直接在网关拒绝不打到后端业务服务节省资源。方案 1SpringCloud Gateway 全局过滤器推荐网关层所有微服务请求统一在这里校验黑名单。1黑名单存储少量用户可以内存 Set生产建议放 Redis方便动态增删拉黑用户不用重启网关。java// 内存黑名单测试用 private final SetString blackUserIdSet Set.of(10001,10086);生产环境使用 RedisSet结构key:black:user:list2自定义 GlobalFilter网关拿到 token 解析出 userId你的业务逻辑解析 token判断是否在黑名单命中直接返回 403。javaimport 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 SetString blackUserIdSet Set.of(10001, 10086); Override public MonoVoid 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如果没有网关在微服务内部拦截 HandlerInterceptorSpringMVC 环境普通微服务所有 Controller 接口拦截。javaimport 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 SetString 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;charsetutf‑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; } }注册拦截器javaConfiguration public class WebConfig implements WebMvcConfigurer { Autowired private UserBlackInterceptor userBlackInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userBlackInterceptor) .addPathPatterns(/**); // 拦截全部接口 } }缺点如果多微服务每个服务都要配置拦截器优先网关统一处理。方案 3AOP 切面拦截不推荐拦截 Controller/RestController 所有方法。缺点异常接口、过滤器、静态资源、response 直接输出场景 AOP 切不到有漏网接口。只适合临时应急。重要细节白名单内部健康检查接口 /actuator/网关过滤器中可以放过健康检查避免拉黑逻辑把服务监控搞挂javaString path request.getPath().value(); if(path.startsWith(/actuator/)){ return chain.filter(exchange); }区分拉黑用户 IDvs 拉黑 IP。你的场景是用户不要用 IP。token 为空未登录请求直接放行黑名单只针对登录用户。少量黑名单用户内存 Set 够用后续黑名单变多一定要迁移 Redis支持运营后台拉黑用户。选型总结方案适用场景优点缺点Gateway 全局 FilterSpringCloud 网关架构✅请求在网关拦截不转发后端性能最好统一管控需要网关服务HandlerInterceptor无网关微服务内部简单SpringMVC 原生多微服务需要每个服务配置AOP 切面临时快速实现编码简单存在部分接口拦截失效风险如果你现在项目有 SpringCloud Gateway直接用方案 1这是生产标准做法。
返回列表