我们有与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会话存储中。但是,当响应返回时,会话将其存储为空。可能是它创建了一个新会话。
浏览了文档,发现我们必须使用SAMLContextProviderLB。 SAML DSL已在使用它。
SO中有多个问题与问题类似,但与负载均衡器/代理不完全相同。
我们如何告诉spring saml在SAML身份验证过程完成之前保留会话?
同样,仅在将我们的应用程序与反向代理(如ZUUL)一起使用时,才会出现此问题。
以下是具有会话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
请注意在使用反向代理的情况下会话ID的差异
任何帮助将不胜感激。
答案 0 :(得分:0)
最后找到了问题所在。
在Zuul中,sensitiveHeaders的默认值为Cookie,Set-Cookie,Authorization
现在,如果我们不设置属性本身,那么这些标头将被视为敏感标头,并且不会向下流向我们的服务。
必须将sensitiveHeaders值设置为空,以便将cookie传递给服务。 Cookie包含我们的JSESSIONID,该ID标识了会话。
zuul:
sensitiveHeaders:
routes:
admin-ui:
path: /admin/**
service-id: admin-ui
strip-prefix: false
customSensitiveHeaders: false