Spring Security 正在重定向到生产服务器上的 localhost
Posted
技术标签:
【中文标题】Spring Security 正在重定向到生产服务器上的 localhost【英文标题】:Spring Security is redirecting to localhost on production server 【发布时间】:2011-04-22 12:59:03 【问题描述】:我有一个安装了 spring-security-core 插件的 grails 应用程序。在本地一切正常。我部署到登台服务器,一切正常。我部署到我们的生产服务器,这是我们登台服务器的镜像。我可以很好地访问不受保护的页面。但是当 Spring Security 启动并尝试执行重定向时,它会重定向到 localhost 而不是 grails.serverURL。
我将尽可能提高日志记录并重新部署,看看我是否可以做出正面或反面。我会在这里发布我的发现。如果有人以前经历过这种情况并且知道可能会发生什么,请告诉我。此外,如果需要查看任何配置文件,我也可以提供这些文件。谢谢。
更新 我在底部的 Config.groovy 中添加了以下内容
grails.plugins.springsecurity.useSecurityEventListener = true
grails.plugins.springsecurity.onAuthorizationEvent = e, appCtx ->
println "here"
println e
在本地,当我尝试访问受保护的页面时,该关闭会被击中 2 次。一次用于初始网址。第二次为 auth url。将此部署到我们的生产服务器,但我什么也没得到。
【问题讨论】:
SecurityConfig.groovy 中是否有任何可能指向 localhost 的内容? spring-security-core 中没有 SecurityConfig.groovy。它使用 Config.groovy。所以,不,没有。 【参考方案1】:重定向是在org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint.commence()
method 中完成的,因此如果您能够借用其中一个生产服务器进行调试,则可以在那里设置断点。
它基于登录表单 uri(例如 /login/auth)构建重定向 URL,但它使用 request.getServerName()
,因此它应该与原始请求相同。请注意,grails.serverURL
在这里没有影响,因为它使用请求的服务器名称、端口、上下文等构建 URL。
将 Apache 或负载平衡器放在 servlet 容器前面可能会影响它,尽管我已经做了这两个并且效果很好。
您是否在 resources.groovy
中进行过任何可能影响此的 bean 自定义?
【讨论】:
谢谢伯特。不,我们的 resources.groovy 实际上是空的。我们确实有 apache 和 mod_proxy 坐在前面。对我来说最大的困惑是为什么它会在一台服务器上运行,而不是在另一台服务器上运行,因为除了通过 DNS 映射到它的域之外,两者的配置方式完全相同。 我将此答案标记为正确,因为我的问题是 request.getServerName() 确实返回了 localhost,这是不正确的。所以我只需要找出发生这种情况的原因。 在我的情况下,它在 nginx 中错误地配置了反向代理,它丢失了:proxy_set_header Host $host;【参考方案2】:如果您的应用程序服务器位于 Web 服务器之后,则此问题可能是由您的 Web 服务器配置引起的。我遇到了同样的问题,并通过在我的 httpd.conf 或 apache2.conf 中使用以下条目来纠正它。在这里……
...这里是样板配置...
################################
# Begin yourdomain.com... #
################################
ProxyRequests Off
ProxyPreserveHost On
<Proxy>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:28080/
ProxyPassReverse / http://localhost:28080/
<Location>
Order allow,deny
Allow from all
</Location>
################################
# ... end yourdomain.com #
################################
【讨论】:
天哪,这解决了我近三天的重定向到本地主机的调查,非常非常感谢! :)【参考方案3】:假设您在 Tomcat 前面有一个网络服务器(apache、nginx 等)作为代理(并且您正在使用 Tomcat)...
在同时允许 http 和 https 的设置中,将单独的 Connector 元素添加到 tomcat 的 conf/server.xml 文件中:
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"
scheme="https" secure="true" proxyName="somehostname.domain" proxyPort="443" />
如果只允许 https,您可以将 scheme、secure、proxyName 和 proxyPort 属性添加到现有的 Connector 元素。
在 apache 配置中,使用额外属性将 *:443 虚拟主机代理到连接器。普通的 http *:80 可以连接到原来的 Connector。
更多信息: http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Proxy_Support http://tomcat.apache.org/tomcat-7.0-doc/proxy-howto.html
【讨论】:
【参考方案4】:我知道这是一个老问题,但我想添加我的发现以帮助其他可能遇到此问题的用户。
除了Burt的回答(我假设你使用的是tomcat),我发现request.getServerName()的返回值也可以通过server.xml设置
即在tomcat 8中 https://tomcat.apache.org/tomcat-8.0-doc/config/http.html
在 server.xml 中有这一行
<Connector protocol="HTTP/1.1"
port="8080" ...
proxyName="localhost"/>
在调用 getServername 时将返回“localhost”。
【讨论】:
以上是关于Spring Security 正在重定向到生产服务器上的 localhost的主要内容,如果未能解决你的问题,请参考以下文章
spring-security login?logout 重定向到登录
Spring Security 不会将 HTTP 重定向到 HTTPS