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

如何针对子域启用或禁用Spring Security认证配置?

针对特定子域启用Spring Security验证的方案

你可以通过两种方式实现仅对指定子域启用安全验证,以下是具体方案:

方案一:基于请求主机名判断(推荐,安全性更高)

直接从请求的主机名(即访问的子域)进行判断,无需依赖请求头,避免请求头被篡改的风险。

修改你的Security配置代码如下:

@Bean
fun securityWebFilterChain(
    http: ServerHttpSecurity
): SecurityWebFilterChain {
    // 定义匹配目标子域的规则
    val testSubdomainMatcher = ServerWebExchangeMatcher { exchange ->
        val host = exchange.request.headers.host?.host
        if ("www.test.example.com".equals(host, ignoreCase = true)) {
            MatchResult.match()
        } else {
            MatchResult.notMatch()
        }
    }

    return http.csrf().disable()
        .cors().configurationSource(corsConfigurationSource())
        .and()
        .authorizeExchange()
            // 仅对匹配到的子域要求认证
            .matchers(testSubdomainMatcher).pathMatchers("/**").authenticated()
            // 其余所有请求直接放行
            .anyExchange().permitAll()
        .and().httpBasic().and().oauth2Login { oauth2 ->
            oauth2.authenticationSuccessHandler(oauthSuccessHandler)
                .authorizedClientService(redisOauthClientService)
        }
        .build()
}

方案二:基于请求头中的基础URL判断

如果必须依赖请求头中的基础URL,可通过解析请求头提取域名进行判断,但需注意请求头可能被伪造,存在安全风险。

假设请求头名为X-Base-Url,修改代码如下:

@Bean
fun securityWebFilterChain(
    http: ServerHttpSecurity
): SecurityWebFilterChain {
    // 基于请求头判断的匹配规则
    val headerBasedMatcher = ServerWebExchangeMatcher { exchange ->
        val baseUrl = exchange.request.headers.getFirst("X-Base-Url")
        baseUrl?.let {
            runCatching {
                val url = URL(it)
                if ("www.test.example.com".equals(url.host, ignoreCase = true)) {
                    return@ServerWebExchangeMatcher MatchResult.match()
                }
            }
        }
        MatchResult.notMatch()
    }

    return http.csrf().disable()
        .cors().configurationSource(corsConfigurationSource())
        .and()
        .authorizeExchange()
            .matchers(headerBasedMatcher).pathMatchers("/**").authenticated()
            .anyExchange().permitAll()
        .and().httpBasic().and().oauth2Login { oauth2 ->
            oauth2.authenticationSuccessHandler(oauthSuccessHandler)
                .authorizedClientService(redisOauthClientService)
        }
        .build()
}

说明

  • 两种方案都是通过ServerWebExchangeMatcher定义匹配规则,仅对符合规则的请求应用认证要求,其余请求直接放行。
  • 优先选择方案一,因为请求的主机名由服务器直接获取,无法被客户端随意篡改,安全性更有保障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:45:35