尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Spring Boot 3.x + Security + OpenFeign:如何避免内部服务调用被重复拦截? - 详解

Spring Boot 3.x + Security + OpenFeign:如何避免内部服务调用被重复拦截? - 详解
📅 发布时间:2026/6/20 8:28:41

Spring Boot 3.x + Security + OpenFeign:如何避免内部服务调用被重复拦截? - 详解

2025-09-28 09:17  tlnshuju  阅读(0)  评论(0)    收藏  举报

网罗开发(小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
大家好,我是展菲!
全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
    • 需求场景分析
    • 常见坑点
    • 解决思路
    • 代码实战
      • 1. Feign 请求加上 client_token
      • 2. 自定义认证过滤器
      • 3. Security 配置双认证逻辑
      • 4. 用户 token 认证
    • 实际场景结合
    • 总结

前言

在微服务架构里,外部请求和内部服务调用的认证逻辑往往不一样。
比如外部用户访问接口时,必须用 user_token 来校验身份;而服务之间(比如服务 A 调用服务 B)只需要用 client_token 来表明这是内部调用,不必再走一遍复杂的用户认证。

但是问题来了:
用户带着 access_token 请求服务 A,A 会先过 Spring Security 的过滤器。这个过滤器里我们要远程调用服务 B 验证 access_token,结果 Feign 请求又被 Security 拦了一次,导致认证死循环。

那要怎么破?本文就来聊聊这个场景的实战解法。

需求场景分析

我们先把需求捋清楚:

  1. 外部请求:

    • 必须携带 user_token
    • 通过服务 A 时,Spring Security 要走用户认证逻辑
  2. 服务间调用:

    • Feign 调用必须带 client_token
    • 服务 B 收到请求时,只要验证这个 client_token 就行,不必再走用户认证
  3. 问题点:

    • 当 A 的 Security 过滤器里用 Feign 调服务 B 验证 access_token 时,这个请求也会被拦截,导致无限套娃

常见坑点

  • 没区分 token 类型:
    用户 token 和 client token 混在一起,所有请求都走同一套拦截逻辑。

  • Feign 默认带全局拦截:
    Spring Security 的 OncePerRequestFilter 会作用于所有请求,包括 Feign 发起的内部请求。

  • 死循环风险:
    A 调 B 校验 token,B 又拦截成用户请求 → 又要去 A 验证 → 死循环。

所以我们必须设计一套机制,让外部请求和内部调用走不同的认证逻辑。

解决思路

  1. 区分两类请求:

    • 用户请求:带 Authorization: Bearer user_token
    • 内部调用:带 X-Client-Token: client_token
  2. Spring Security 配置双认证链:

    • 用户请求必须走 JWT 校验逻辑
    • 内部调用只校验 client_token,绕过用户认证
  3. Feign 请求统一加 client_token:

    • 用 RequestInterceptor 给 Feign 请求自动加 X-Client-Token

代码实战

下面用 Spring Boot 3.x 写一个简化版 Demo,演示完整流程。

1. Feign 请求加上 client_token

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfig {
@Bean
public RequestInterceptor clientTokenInterceptor() {
return (RequestTemplate template) -> {
// 模拟内部服务调用的 client_token,可以从配置中心或 Vault 获取
template.header("X-Client-Token", "my-client-token-123");
};
}
}

这样每次服务 A 调用服务 B,都会带上 X-Client-Token。

2. 自定义认证过滤器

我们需要两个过滤器,一个处理用户 token,一个处理 client token。

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
public class ClientTokenFilter extends OncePerRequestFilter {
private final String CLIENT_TOKEN = "my-client-token-123";
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String clientToken = request.getHeader("X-Client-Token");
if (clientToken != null && clientToken.equals(CLIENT_TOKEN)) {
// 直接认证为内部服务角色
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken("internal-service", null, null);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(request, response);
}
}

这里的逻辑很简单:

  • 如果请求头有 X-Client-Token 并且正确 → 直接放行,视为内部请求
  • 没有的话就交给后面的用户认证逻辑去处理

3. Security 配置双认证逻辑

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable());
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
);
// client token filter 优先级要高于 user token filter
http.addFilterBefore(new ClientTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(new UserTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}

这里我们把 ClientTokenFilter 放在前面,这样内部调用会优先匹配,不会再进入用户认证逻辑。

4. 用户 token 认证

public class UserTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String userToken = authHeader.substring(7);
// TODO: 调用服务 B 验证 user_token,有效的话设置用户上下文
// 这里省略 JWT 验证逻辑
}
filterChain.doFilter(request, response);
}
}

这样就能保证:

  • 外部请求 → Authorization: Bearer user_token → 走 UserTokenFilter
  • 内部调用 → X-Client-Token: client_token → 走 ClientTokenFilter

实际场景结合

设想一下:

  • 用户小明用 app 登录,请求 /api/orders 带着 user_token。
  • 服务 A 收到请求,要调用服务 B 校验 user_token。
  • Feign 调用时带上了 X-Client-Token,所以服务 B 不会再拦截成用户请求,而是识别成内部调用。
  • 服务 B 验证成功后返回结果,A 才继续执行业务逻辑。

这样就避免了死循环,既保证了安全性,又把内部调用和外部请求分开了。

总结

这个问题的核心是 区分外部请求和内部调用的认证链路:

  1. 给 Feign 调用统一加 client_token
  2. 在 Security 里加一个 ClientTokenFilter,专门处理内部请求
  3. 用户请求继续走 JWT 或 access_token 的逻辑
  4. 通过过滤器顺序,避免 Feign 调用再触发用户认证,彻底解决死循环

相关新闻

  • 物理笔记
  • GreenPlum - Get field types
  • 搭建环境

最新新闻

  • PostgreSQL 数据迁移实战手册:高效备份与恢复的进阶技巧
  • 掀起波澜: Elastic 被评为 Forrester Wave™ 《2026 年第二季度扩展检测与响应平台》中的强劲表现者
  • ArcGIS模型构建器批量处理NetCDF多维气象数据的实战指南
  • OBS直播教程 :OBS美颜从安装到使用完整教程
  • 3分钟掌握DLSS Swapper:一键智能切换DLSS版本,免费提升游戏性能30%
  • 2026年众智商学院SCMP在职人员备考笔记怎么做?复习方法和记忆技巧分享 - 众智商学院职业教育

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号