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

Spring Security 5.7.3:如何从子域名获取RegistrationId

从子域名获取Spring Security SAML2的registrationId解决方案

针对Spring Security 5.7.3版本,要实现从子域名提取registrationId,核心是替换默认的RelyingPartyRegistrationResolver,自定义逻辑从请求的主机地址中解析出子域名作为registrationId,具体步骤如下:

1. 自定义RelyingPartyRegistrationResolver实现类

创建自定义解析器,从请求的serverName中提取子域名,再根据该ID获取对应的SAML2依赖方注册信息:

import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
import javax.servlet.http.HttpServletRequest;

public class SubdomainRelyingPartyRegistrationResolver implements RelyingPartyRegistrationResolver {

    private final RelyingPartyRegistrationRepository repository;
    // 配置你的根域名,比如company.com
    private final String rootDomain = "company.com";

    public SubdomainRelyingPartyRegistrationResolver(RelyingPartyRegistrationRepository repository) {
        this.repository = repository;
    }

    @Override
    public RelyingPartyRegistration resolve(HttpServletRequest request) {
        String serverName = request.getServerName();
        // 提取子域名作为registrationId
        String registrationId = extractSubdomain(serverName);
        if (registrationId == null) {
            return null;
        }
        return repository.findByRegistrationId(registrationId);
    }

    @Override
    public RelyingPartyRegistration resolve(HttpServletRequest request, String registrationId) {
        // 保留原有按ID查找的逻辑,兼容其他场景
        return repository.findByRegistrationId(registrationId);
    }

    private String extractSubdomain(String serverName) {
        if (!serverName.endsWith("." + rootDomain)) {
            return null;
        }
        // 拆分出子域名部分,比如someregid.company.com -> someregid
        return serverName.substring(0, serverName.length() - (rootDomain.length() + 1));
    }
}

2. 集成自定义解析器到Security配置

在SecurityFilterChain配置中,替换默认解析器,同时调整loginProcessingUrl为固定路径(不再需要从路径获取registrationId):

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SecurityConfig {

    private final RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;

    public SecurityConfig(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
        this.relyingPartyRegistrationRepository = relyingPartyRegistrationRepository;
    }

    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 自定义解析器实例
        SubdomainRelyingPartyRegistrationResolver customResolver = 
            new SubdomainRelyingPartyRegistrationResolver(relyingPartyRegistrationRepository);

        http
            .authorizeRequests()
                .antMatchers("/authorized").hasRole("USER")
                .anyRequest().authenticated()
            .and()
                .saml2Login()
                    .successHandler(new MySamlLoginSuccessHandler())
                    .loginProcessingUrl("/saml/SSO") // 固定路径,不再需要{registrationId}
                    .relyingPartyRegistrationResolver(customResolver); // 设置自定义解析器

        return http.build();
    }
}

关键说明

  • 自定义解析器通过request.getServerName()获取完整域名,拆分出子域名作为registrationId,再从RelyingPartyRegistrationRepository中查找对应的注册配置。
  • 调整loginProcessingUrl为固定的/saml/SSO,因为现在不再依赖路径变量传递registrationId。
  • 子域名提取逻辑可以根据实际域名结构调整,比如处理多级子域名、根域名带端口的场景等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:15:44