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

如何配置Spring应用仅响应指定域名的请求?

解决方案:Spring应用仅响应指定域名请求(无反向代理)

针对你的需求,直接在Spring应用内部实现请求域名校验,无需依赖反向代理,同时支持动态配置允许的域名,具体方案如下:

方案一:自定义Spring MVC拦截器

通过拦截所有请求,校验请求头中的Host字段是否匹配配置的允许域名,不匹配则直接返回403禁止访问。

1. 配置允许的域名

在application.properties(或application.yml)中添加配置:

# 允许访问的域名,支持命令行参数覆盖:--allowed.domain=your-custom-domain.example.com
allowed.domain=myservice.example.com

2. 创建请求拦截器

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class DomainValidationInterceptor implements HandlerInterceptor {

    @Value("${allowed.domain}")
    private String allowedDomain;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestHost = request.getHeader("Host");
        // 移除端口(如果有的话),只校验域名部分
        if (requestHost != null) {
            requestHost = requestHost.split(":")[0];
        }

        // 校验Host是否匹配允许的域名
        if (allowedDomain.equals(requestHost)) {
            return true;
        }

        // 不匹配则返回403
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.getWriter().write("Access Denied: Invalid Domain");
        return false;
    }
}

3. 注册拦截器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final DomainValidationInterceptor domainValidationInterceptor;

    @Autowired
    public WebConfig(DomainValidationInterceptor domainValidationInterceptor) {
        this.domainValidationInterceptor = domainValidationInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 对所有请求生效
        registry.addInterceptor(domainValidationInterceptor).addPathPatterns("/**");
    }
}

方案二:利用Spring Security实现(适合已集成Security的场景)

如果你的应用已经使用Spring Security,可以通过自定义请求匹配器来限制域名:

1. 配置允许的域名(同方案一)

allowed.domain=myservice.example.com

2. 配置Security规则

import org.springframework.beans.factory.annotation.Value;
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;
import org.springframework.security.web.util.matcher.RequestMatcher;

import jakarta.servlet.http.HttpServletRequest;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Value("${allowed.domain}")
    private String allowedDomain;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                // 仅允许指定域名的请求访问所有接口
                .requestMatchers(allowedDomainMatcher()).permitAll()
                // 其他所有请求拒绝访问
                .anyRequest().denyAll()
        );
        return http.build();
    }

    private RequestMatcher allowedDomainMatcher() {
        return new RequestMatcher() {
            @Override
            public boolean matches(HttpServletRequest request) {
                String requestHost = request.getHeader("Host");
                if (requestHost != null) {
                    requestHost = requestHost.split(":")[0];
                }
                return allowedDomain.equals(requestHost);
            }
        };
    }
}

额外优化:禁止IP直接访问

如果需要彻底禁止通过IP(如198.51.100.1:8080)访问,可在拦截逻辑中添加判断:

// 在preHandle方法中添加
if (requestHost != null && requestHost.matches("\\d+\\.\\d+\\.\\d+\\.\\d+")) {
    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
    response.getWriter().write("Access Denied: IP Access Not Allowed");
    return false;
}

动态配置说明

  • 部署时可通过命令行参数覆盖域名配置:
    java -jar your-app.jar --allowed.domain=custom-service.example.com --server.port=8080
    
  • 多机器部署时,只需在每台机器的启动命令或配置文件中设置对应的allowed.domain即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:40:33