Spring SAML 2.0动态依赖方注册在Nginx反向代理下失效
问题:Spring SAML2动态IdP部署EKS集群后登录重定向失败
业务场景:通过orgId查询参数从其他服务获取对应IdP配置,实现动态选择IdP。本地以Okta作为IdP时功能正常,甚至支持SLO;但部署到EKS集群后,访问http://dev.org.com/services/sso/auth-sso?orgId=<id>可正常跳转至Okta完成登录,登录后重定向阶段无法触发根路径/的认证入口,最终跳转到http://dev.org.com/auth-sso?error。
已尝试的操作:
- 在application.yml中设置context-path,无效果
- 查阅负载均衡相关文档,发现当前使用的Spring SAML版本不识别
SAMLContextProviderLB或SAMLContextProviderImpl类
依赖配置(build.gradle.kt)
constraints { implementation("org.opensaml:opensaml-core:4.1.1") implementation("org.opensaml:opensaml-saml-api:4.1.1") implementation("org.opensaml:opensaml-saml-impl:4.1.1") } // spring implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-security") // saml2 implementation("org.springframework.security.extensions:spring-security-saml2-core:2.0.0.M31") implementation("org.springframework.security:spring-security-saml2-service-provider:5.7.4")
安全配置Bean(SamlConfig类)
SecurityFilterChain
@Bean fun securityWebFilterChain(http: HttpSecurity): SecurityFilterChain { http .authorizeRequests { it .mvcMatchers("/auth-sso").permitAll() .mvcMatchers("/actuator/*").permitAll() .anyRequest().authenticated() } .saml2Login { it.loginPage("/auth-sso") } .saml2Logout{} return http.build() }
自定义RelyingPartyRegistrationRepository
@Bean protected fun relyingPartyRegistrations(): RelyingPartyRegistrationRepository? { return LazyRelyingPartyRegistrationRepository() }
接口代码
/auth-sso 接口
@GetMapping(value = ["/auth-sso"]) @ResponseBody fun login( @RequestParam(name = "orgId", required = true) orgId: String, request: HttpServletRequest, response: HttpServletResponse ) { try { val id = runBlocking { findIdpConfigurationUseCase.execute(object : UserOrganizationLogin { override val organizationId = organizationId override val token: String? = null }) } val spInitiateUrl = "saml2/authenticate/$id" log.debug("Redirecting to {}", spInitiateUrl) response.sendRedirect(spInitiateUrl) } catch (e: Exception) { log.error("Error preparing assertion info: {}", e) response.sendRedirect(MessageFormat.format(environment.getRequiredProperty(HOME_URL), "")) } }
认证入口 / 接口
@RequestMapping("/") fun index(model: Model, @AuthenticationPrincipal principal: Saml2AuthenticatedPrincipal, response: HttpServletResponse) { log.debug("User is authenticated!!!") val loginInfo = runBlocking { loginUserUseCase.execute(principal) } response.sendRedirect( environment.getRequiredProperty(HOME_URL) + MessageFormat.format(environment.getRequiredProperty(SSO_HOME_PARAMS), loginInfo.token, loginInfo.organizationId) ) }
内容的提问来源于stack exchange,提问作者Jeancarlo Fontalvo
相关产品推荐
相关产品推荐

