我们有与 Spring SAML 集成的 Spring Boot 应用程序。我们还在 WebSecurityConfigurerAdapter 中使用 Spring SAML DSL 来启动 SAML 上下文。
以下是我们如何使用 SAML DSL 配置 SAML 的 http 安全性。
http.authorizeRequests().antMatchers("/saml*").permitAll().anyRequest().authenticated().and().apply(saml())
.userDetailsService(sAMLUserDetailsService).serviceProvider()
.keyStore()
.storeFilePath(this.sslResource.getKeyStore())
.password(this.sslResource.getKeyStorePassword()).keyname(this.sslResource.getKeyAlias())
.keyPassword(this.sslResource.getKeyStorePassword()).and().protocol(this.serverResource.getProtocol())
.hostname(String.format("%s:%s", "localhost", 9000))
.basePath("/admin").and().identityProvider()
.metadataFilePath(samlMetadataUrl);
注意主机名和端口。我已经给出了代理的主机名和端口。
我们的启动应用程序正在 https://localhost:8443/admin 上运行。在这种情况下,SAML 工作得非常好。
现在我们尝试使用 Zuul 作为我们应用程序的反向代理。
现在 zuul 将在 localhost:9000 上运行。这是zuul路由配置
zuul:
routes:
admin-ui:
path: /admin/**
service-id: admin-ui
strip-prefix: false
customSensitiveHeaders: false
现在,当我们通过 https://localhost:9000/admin/ 访问我们的应用程序时并尝试使用 SAML 登录,在 Spring SAML 中进行身份验证时出现以下错误。
InResponseToField of the Response doesn't correspond to sent message a20jj965cg1ja8g01gbjg1d542dhg1e
我发现在发送 AuthNRequest 时,消息 ID 被存储到 HTTP session 存储中。但是当响应返回时, session 存储就清空了。可能是它创建了一个新 session 。
浏览文档,发现我们必须使用 SAMLContextProviderLB。 SAML DSL 已使用该方法。
SO 中有多个问题与该问题类似,但与负载均衡器/代理不完全一样。
我们如何告诉 spring saml 保留 session 直到 SAML 身份验证过程完成?
同样,这个问题仅在将我们的应用程序与 ZUUL 等反向代理一起使用时出现。
以下是带有 session ID 的日志记录语句:
工作案例
发送请求之前
o.s.s.saml.storage.HttpSessionStorage : Storing message a29jbce497fg0hjgaa8cf669hh1e8h to session D1694D9C4C19E5A4B0D3768A290FC144
收到回复后
o.s.s.saml.storage.HttpSessionStorage : Message a29jbce497fg0hjgaa8cf669hh1e8h found in session D1694D9C4C19E5A4B0D3768A290FC144, clearing
如果通过反向代理(ZUUL)发送
发送请求之前
o.s.s.saml.storage.HttpSessionStorage : Storing message a4i8jj75fe214b70bdf27dg8idc2a9 to session F26763C072560A421B54CBBB2C4BC8C3
收到回复后
o.s.s.saml.storage.HttpSessionStorage : Message a4i8jj75fe214b70bdf27dg8idc2a9 not found in session E59A025009ADD06BB3F35F8250A66208
注意反向代理情况下 session ID 的差异
如有任何帮助,我们将不胜感激。
最佳答案
终于找到问题了。
在 Zuul 中,sensitiveHeaders 的默认值为 Cookie,Set-Cookie,Authorization
现在,如果我们不设置属性本身,那么这些 header 将被视为敏感 header ,并且不会向下游传输到我们的服务。
必须将sensitiveHeaders 值设置为空,以便将cookie 传递到服务。 Cookie 包含我们的 JSESSIONID,它可以识别 session 。
zuul:
sensitiveHeaders:
routes:
admin-ui:
path: /admin/**
service-id: admin-ui
strip-prefix: false
customSensitiveHeaders: false
关于java - 具有反向代理的 Spring SAML - 响应的响应字段与发送的消息不对应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57067489/