如何配置Spring Security SAML2的baseUrl使认证请求通过网关
SAML2 SSO网关转发重定向问题解决方案
问题核心
后端服务生成的SAML认证重定向URL用了自身的8080端口,而非网关的8090端口,导致请求跳转到后端直接地址,而非通过网关转发。这是因为Spring Security默认根据当前请求上下文生成URL,若网关转发时未传递外部地址头信息,后端无法识别真实的外部访问地址。
具体解决步骤
1. 配置后端服务识别网关转发头
在后端服务的配置文件(application.yml或application.properties)中添加:
server: forward-headers-strategy: FRAMEWORK
这个配置让Spring自动识别网关转发的X-Forwarded-Host、X-Forwarded-Proto等头信息,生成正确的外部访问URL。
2. 配置网关路由与转发头
确保网关将所有SAML相关请求转发到后端服务,并添加必要的转发头,让后端知道外部访问地址:
spring: cloud: gateway: routes: # 优先处理SAML相关请求 - id: saml-route uri: http://localhost:8080 predicates: - Path=/saml2/** filters: - AddRequestHeader=X-Forwarded-Host, localhost:8090 - AddRequestHeader=X-Forwarded-Proto, http # 处理其他业务请求 - id: app-route uri: http://localhost:8080 predicates: - Path=/** filters: - AddRequestHeader=X-Forwarded-Host, localhost:8090 - AddRequestHeader=X-Forwarded-Proto, http
3. 调整SAML依赖方注册配置
在后端的SAML注册配置中,显式指定断言消费者服务(ACS)的地址为网关地址,确保IdP回调时指向网关:
@Configuration public class SamlConfig { @Bean public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { // 替换成你的IdP元数据地址或配置 String idpMetadataUrl = "https://your-idp.com/metadata"; RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("your-reg-id") .idpMetadataLocation(idpMetadataUrl) // 指定ACS地址为网关地址 .assertionConsumerServiceLocation("http://localhost:8090/saml2/SSO/your-reg-id") .build(); return new InMemoryRelyingPartyRegistrationRepository(registration); } }
4. 调整Spring Security认证配置
确保后端的Security配置中,SAML的登录、回调路径与网关转发路径一致:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .saml2Login() // 登录处理路径要和网关转发的路径匹配 .loginProcessingUrl("/saml2/SSO/{registrationId}") .and() .saml2Logout() .logoutUrl("/saml2/logout/{registrationId}"); } }
依赖配置
网关依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>3.0.4</version> </dependency>
后端服务SAML依赖
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-saml2-service-provider</artifactId> <version>5.5.2</version> </dependency> <dependency> <groupId>org.opensaml</groupId> <artifactId>opensaml-core</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>org.opensaml</groupId> <artifactId>opensaml-saml-api</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>org.opensaml</groupId> <artifactId>opensaml-saml-impl</artifactId> <version>4.1.1</version> </dependency>
内容的提问来源于stack exchange,提问作者Виктор Кольцо
相关产品推荐
相关产品推荐

