You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot微服务如何限制直接访问,仅允许通过API网关调用?

限制Owner服务直接访问的几种可行方案

1. 自定义请求头校验(推荐本地/开发环境快速验证)

让Security服务通过Feign调用Owner时,添加专属内部请求头,Owner服务校验该头的合法性,仅允许携带合法头的请求通行。

实现步骤:

  • 在Security服务配置Feign拦截器,给所有调用Owner的请求添加标识头:
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {
    @Bean
    public RequestInterceptor internalRequestInterceptor() {
        return template -> {
            // 添加内部服务调用专属标识
            template.header("X-Internal-Request", "security-service");
        };
    }
}
  • 在Owner服务添加过滤器,校验请求头:
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class InternalRequestFilter implements Filter {
    private static final String INTERNAL_HEADER = "X-Internal-Request";
    private static final String VALID_VALUE = "security-service";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;
        String headerVal = httpReq.getHeader(INTERNAL_HEADER);

        if (VALID_VALUE.equals(headerVal)) {
            chain.doFilter(request, response);
        } else {
            HttpServletResponse httpResp = (HttpServletResponse) response;
            httpResp.setStatus(HttpServletResponse.SC_FORBIDDEN);
            httpResp.getWriter().write("Direct access is not allowed");
        }
    }
}

2. IP白名单限制(适合固定IP部署的生产环境)

在Owner服务中配置IP白名单,仅允许Security服务的IP发起请求。本地环境若都是localhost,该方案效果有限,但跨机器部署时很实用。

示例(用Spring MVC拦截器实现):

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class IpWhitelistConfig implements WebMvcConfigurer {
    // 替换为Security服务的实际IP,生产环境可从配置文件读取
    private static final List<String> ALLOWED_IPS = List.of("127.0.0.1", "192.168.1.100");

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                String clientIp = request.getRemoteAddr();
                if (ALLOWED_IPS.contains(clientIp)) {
                    return true;
                }
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                response.getWriter().write("IP not permitted");
                return false;
            }
        });
    }
}

3. Spring Security权限控制(生产环境标准方案)

给Owner服务的接口配置专属权限,仅允许携带合法服务间认证凭证的请求访问。直接访问的请求因无有效凭证被拒绝。

核心思路:

  • Security服务通过Feign调用Owner时,携带服务间专属JWT令牌(或其他认证凭证)到请求头。
  • Owner服务配置Spring 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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class OwnerSecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // 仅允许拥有SERVICE_INTERNAL权限的请求访问所有接口
                .anyRequest().hasAuthority("SERVICE_INTERNAL")
            )
            // 配置JWT资源服务器(根据实际JWT实现调整)
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(/* 自定义权限转换器 */)));
        return http.build();
    }
}

4. 网络层面隔离(生产环境终极方案)

  • Docker部署:创建专属内部网络,Owner服务仅加入内部网络,不暴露端口到宿主机,仅Security服务能在内部网络访问它。
  • Kubernetes部署:配置NetworkPolicy,仅允许Security服务的Pod访问Owner服务的端口。
  • 本地环境:调整防火墙规则,禁止外部请求访问8081端口,仅允许本地Security服务进程发起的请求(比如Windows防火墙添加入站规则,拒绝所有IP访问8081,仅放行127.0.0.1的特定进程)。

内容的提问来源于stack exchange,提问作者bhavesh agrawal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:54:22