Spring Boot 2 和 Kotlin 的“URL 未标准化”
Posted
技术标签:
【中文标题】Spring Boot 2 和 Kotlin 的“URL 未标准化”【英文标题】:"URL was not normalized" with Spring Boot 2 and Kotlin 【发布时间】:2019-03-08 11:38:40 【问题描述】:在我当前的项目中,我们在Openshift
和Kubernetes
中部署了几个Spring Boot 1.5.4.RELEASE
微服务。我们已经配置了一个 Apache Proxy Balancer:
From To
/msa/microname1 -> /
/msa/microname2 -> /
...
最近我们介绍了Spring Boot 2
,并使用Kotlin
开发了一个新的微服务。考虑到/health
和/info
之类的url 放在/actuator
路径下,我们以相同的方式配置平衡器。
现在,当我们使用这个新微服务的任何端点(/health
或我们的任何端点)时,我们都会遇到如下错误:
org.springframework.security.web.firewall.RequestRejectedException: 由于 URL 未规范化,请求被拒绝...
我们在微服务中截取的路径开头多了一个斜线://<path_to_resource>
当我使用微服务 url 时,我可以毫无问题地获得资源,但是当使用代理平衡器映射时,我们遇到了上述问题。
我们检查了我们的代理平衡器,它的配置方式与其他平衡器相同。
我们必须考虑Spring Boot 2
上的任何额外配置吗?
这可能是与Kotlin
相关的问题吗?
更新
作为一项调整,我们已将 DefaultHttpFirewall 配置为允许 url 加斜杠,但这并不能解决双斜杠的问题。它只是掩盖了问题。
@Bean
fun allowUrlEncodedSlash(): HttpFirewall
var firewall: DefaultHttpFirewall = DefaultHttpFirewall()
firewall.setAllowUrlEncodedSlash(true)
return firewall
override fun configure(web: WebSecurity)
web.httpFirewall(allowUrlEncodedSlash())
【问题讨论】:
【参考方案1】:检查这个答案:https://***.com/a/48644226/10451721
这似乎与您的问题相同,但使用的是 Java 而不是 Kotlin。
默认情况下,Spring 不喜欢 URL 中的 //
。
我已经为您转换了链接答案中的 Java:
@Bean
fun allowUrlEncodedSlashHttpFirewall(): HttpFirewall
val firewall = StrictHttpFirewall()
firewall.setAllowUrlEncodedSlash(true)
return firewall
【讨论】:
是的,我们昨天做了同样的事情,但是我们不方便修改 HttpFirewall。我们仍在寻找根本原因,因为我们没有添加任何额外的栏。至少我是这么认为的。【参考方案2】:通过在我们的平衡器中向应用程序添加上下文来解决。 现在我们所有的端点在我们的微服务中都有一个上下文,在 application.yml 中定义。
From To
/msa/microname1 -> /
/msa/microname2 -> /
/msa/Kotlinname/kt -> /kt
【讨论】:
以上是关于Spring Boot 2 和 Kotlin 的“URL 未标准化”的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 2 和 Kotlin 的“URL 未标准化”
使用 Spring Boot 2 和 Kotlin 进行 Jackson 反序列化,无法构造 `java.time.LocalDate` 的实例
带有 Spring Boot 2.0 @ConfigurationProperties 的 Kotlin 无法正常工作