我在下面列出了一些选项:
设置反向代理
根据ServletRequest 的Javadoc:HttpServletRequest.getServerName() 将是:
Host 标头值中 ':' 之前部分的值(如果有),或
解析的服务器名称,或服务器 IP 地址。
这意味着您可以配置您的代理以确保正确设置主机标头(请注意,像 WebSphere 这样的一些容器虽然不遵守规范)。
使用容器配置覆盖
如果您使用反向代理,许多服务器的设置可以覆盖此值。有一个相当不错的thread on the Spring forums,我在下面总结了更多信息。
如果您使用的是 Tomcat,我会参考 Reverse Proxy setup page。一种配置方法是将Http Connector 配置为具有proxyName 属性以覆盖由HttpServletRequest.getServerName() 返回的值和proxyPort 以覆盖由HttpServletRequest.getServerPort() 返回的值。示例配置可能如下所示:
server.xml
<Connector scheme="https" secure="true"
proxyPort="443" proxyName="example.com"
port="8009" protocol="AJP/1.3"
redirectPort="8443" maxThreads="750"
connectionTimeout="20000" />
Websphere 有几个 custom properties 做同样的事情。
com.ibm.ws.webcontainer.extractHostHeaderPort = true
trusthostheaderport = true
httpsIndicatorHeader = com.ibm.ws.httpsIndicatorHeader
如果您不使用这些容器或需要支持多个域,则需要查阅容器文档。
自定义 AuthenticationDetailsSource
当然 Spring Security 非常灵活,因此您始终可以提供 AuthenticationDetailsSource 的自定义实现,该实现返回一个 ServiceAuthenticationDetails 实例,该实例以您希望的任何方式查找服务 URL。