You need to enable JavaScript to run this app. 如何针对特定域名绕过已认证端点的Spring Security校验?
优惠活动
大模型
产品
解决方案
定价
更多

如何针对特定域名绕过已认证端点的Spring Security校验?

实现方案

该需求可正常实现,核心逻辑是在权限校验流程中增加「请求端点+来源域名」的组合判断分支,对符合条件的请求跳过JWT认证,具体操作如下:

步骤1:修改SecurityConfig,新增自定义放行规则

不需要把/sample-endpoint加入全局公开路径列表,通过自定义RequestMatcher匹配来自xyz.com的目标端点请求,单独放行:

SecurityConfig修改后代码

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    public static final String[] unauthedUrls = { "healthcheck","some-other-endpoint"}  

    // 自定义匹配器:匹配来自xyz.com的/sample-endpoint请求
    private RequestMatcher xyzDomainSampleRequestMatcher() {
        return request -> {
            // 先匹配请求路径
            if (!"/sample-endpoint".equals(request.getRequestURI())) {
                return false;
            }
            // 匹配来源域名,优先取跨域请求的Origin头,无Origin头时取请求来源主机名
            String origin = request.getHeader(HttpHeaders.ORIGIN);
            if (origin != null) {
                // 去除协议、端口后匹配主域名,需要匹配子域名可改为endsWith("xyz.com")
                return origin.replaceFirst("^https?://", "")
                        .replaceFirst(":\\d+$", "")
                        .equals("xyz.com");
            }
            return "xyz.com".equals(request.getRemoteHost());
        };
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable()
                .csrf().disable()
                .cors().and()
                .headers().frameOptions().disable().and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
                .addFilterAfter(jwtSecurityFilter, UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                // 新增规则:匹配到xyz.com访问sample-endpoint的请求直接放行
                .requestMatchers(xyzDomainSampleRequestMatcher()).permitAll()
                .antMatchers(unauthedUrls).permitAll()
                .anyRequest().authenticated();
    }
}

步骤2:修改JwtSecurityFilter,避免放行请求报错

需要调整过滤器的异常判断逻辑,避免符合放行条件的请求因为没有携带JWT被抛出异常、打印错误日志:

JwtSecurityFilter修改后代码(仅修改catch块部分)

private void setAuthenticationContext(HttpServletRequest request) {
    try {
        String token = getJwt(request);
        if (StringUtils.isBlank(token)) {
            throw new RuntimeException("Authorization token not provided");
        }
        // 此处省略原有业务逻辑
    } catch (Exception ex) {
        boolean needSkipAuth = false;
        if (request != null) {
            // 判断是否为公开路径
            boolean isPublicUrl = Arrays.stream(SecurityConfig.unauthedUrls)
                    .anyMatch(url -> request.getRequestURI().contains(url));
            // 判断是否为xyz.com访问sample-endpoint的放行请求
            boolean isXyzDomainRequest = "/sample-endpoint".equals(request.getRequestURI());
            if (isXyzDomainRequest) {
                String origin = request.getHeader(HttpHeaders.ORIGIN);
                if (origin != null) {
                    isXyzDomainRequest = origin.replaceFirst("^https?://", "")
                            .replaceFirst(":\\d+$", "")
                            .equals("xyz.com");
                } else {
                    isXyzDomainRequest = "xyz.com".equals(request.getRemoteHost());
                }
            }
            needSkipAuth = isPublicUrl || isXyzDomainRequest;
        }
        if (needSkipAuth) {
            // 符合放行条件,直接返回不处理异常
            return;
        }
        LOGGER.warn("Unable to authenticate request: {} {}", ex.getMessage(), request == null ? null : request.getRequestURI());
    }
}

注意事项

  • 如果需要支持xyz.com的所有子域名(如a.xyz.com、b.xyz.com),可以把域名匹配逻辑从equals("xyz.com")改为endsWith("xyz.com")
  • 如果是服务端之间的调用场景(无Origin头),建议配合IP白名单校验,提前解析xyz.com对应的IP段进行匹配,避免域名伪造的安全问题
  • 如果你使用的是Spring Security 5.7+版本,WebSecurityConfigurerAdapter已经被标记为废弃,可以改为用SecurityFilterChain的方式实现配置,逻辑和上述方案一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 23:36:08