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

SpringBoot单实例如何为不同URL配置差异化HTTPS认证?

SpringBoot单实例多路径差异化HTTPS认证实现方案

核心思路:放弃SpringBoot全局client-auth: need的强制双向认证配置,将容器SSL握手规则调整为「请求客户端证书但不强制校验」,再通过容器层拦截器针对指定路径做证书强校验,单进程单端口即可同时满足两类路径的认证要求,无需启动额外实例或端口。

步骤1:配置基础SSL全局参数

修改application.yml配置,注意不要将client-auth设为need:

server:
  port: 443
  ssl:
    enabled: true
    key-store: classpath:server.p12 # 服务端证书
    key-store-password: 服务端证书密码
    key-store-type: PKCS12
    trust-store: classpath:truststore.p12 # 导入所有信任的后端调用方根CA证书
    trust-store-password: 信任库密码
    client-auth: want

配置说明:client-auth: want表示SSL握手阶段服务端会主动向客户端请求证书,但客户端未提供证书时不会直接断开连接,为后续路径级差异化校验留出入口。

步骤2:添加容器层路径级双向认证校验

以SpringBoot默认内嵌Tomcat为例,自定义容器Valve(执行时机早于Spring过滤器、拦截器,安全性更高),拦截/backend/**路径强制校验客户端证书:

import org.apache.catalina.valves.ValveBase;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletException;
import java.io.IOException;
import java.security.cert.X509Certificate;

@Configuration
public class SslPathConfig {

    @Bean
    public ServletWebServerFactory tomcatCustomizer() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addContextValves(new BackendMutualAuthValve());
        return factory;
    }

    private static class BackendMutualAuthValve extends ValveBase {
        private static final String BACKEND_PATH_PREFIX = "/backend/";

        @Override
        public void invoke(org.apache.catalina.connector.Request request, javax.servlet.http.HttpServletResponse response) throws IOException, ServletException {
            String uri = request.getRequestURI();
            if (uri.startsWith(BACKEND_PATH_PREFIX)) {
                // 从请求上下文获取客户端提交的证书链
                X509Certificate[] clientCerts = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
                if (clientCerts == null || clientCerts.length == 0) {
                    response.sendError(401, "Backend API access requires valid client certificate");
                    return;
                }
                // 可选:自定义证书校验逻辑,比如校验证书DN、序列号、是否在吊销列表等
                validateCert(clientCerts[0]);
            }
            // 校验通过或非后端路径,继续执行后续请求流程
            getNext().invoke(request, response);
        }

        private void validateCert(X509Certificate clientCert) {
            // 示例:校验证书颁发者是否为信任CA
            String issuer = clientCert.getIssuerX500Principal().getName();
            if (!issuer.contains("YOUR_TRUSTED_CA_NAME")) {
                throw new SecurityException("Client certificate issued by untrusted CA");
            }
        }
    }
}

步骤3:配置前端路径Token认证

/frontend/**路径的Token认证和常规接口认证逻辑一致,通过Spring Security拦截器、自定义Filter实现即可,示例配置:

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.authentication.www.BasicAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class PathAuthConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeHttpRequests(auth -> auth
                        // 后端路径已在容器层完成证书校验,可直接放行或补充细粒度权限控制
                        .antMatchers("/backend/**").permitAll()
                        // 前端路径走自定义Token校验过滤器
                        .antMatchers("/frontend/**")
                        .addFilterBefore(new TokenVerifyFilter(), BasicAuthenticationFilter.class)
                        .authenticated()
                        // 其余路径直接拒绝
                        .anyRequest().denyAll()
                );
        return http.build();
    }
}

注意事项

  • 整套方案仅需启动一个SpringBoot进程、监听一个HTTPS端口,无需额外部署反向代理或开放HTTP端口,性能损耗可忽略
  • 双向认证校验必须放在容器Valve/拦截器层实现,不要放在Spring Filter层,避免非法请求进入Spring上下文带来安全风险
  • 若使用Undertow、Jetty等其他内嵌容器,核心逻辑一致,替换为对应容器的前置请求拦截组件即可
  • 信任库(truststore)必须提前导入所有后端调用方客户端证书对应的根CA,否则会出现合法证书无法通过校验的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 16:36:43