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 - 禁用注销重定向

重写 spring-security 重定向 URL

Spring Security 不会将 HTTP 重定向到 HTTPS

grails spring-security-ui 插件重定向回应用程序

Spring Security:会话过期而不重定向到过期网址?