51

我有一个 Spring Web 应用程序,由 Spring Security 保护,在 EC2 上运行。EC2 实例前面是一个带有 SSL 证书的弹性负载均衡器(https 终止于负载均衡器,即端口 443 -> 端口 80),因此从 Tomcat 的角度来看,入站请求是 HTTP。

我的登录表单提交到 https,但是随后的重定向转到 http(成功或失败)。认证成功,我可以回到https,我已经登录了。

我的登录配置如下所示:

<security:form-login
    default-target-url="/home"
    login-page="/"
    login-processing-url="/processlogin"
    authentication-failure-url="/?login_error=1"/>

我需要更改什么才能使 default-target-url 和 authentication-failure-url 转到 https?

  • 雄猫 6
  • Spring 安全 3.0.x
4

10 回答 10

30

您的 spring 配置应该与使用的协议无关。如果您使用“requires-channel”之类的东西,迟早会遇到问题,特别是如果您想将相同的应用程序部署到没有 https 的开发环境中。

相反,请考虑正确配置您的 tomcat。您可以使用RemoteIpValve做到这一点。根据负载均衡器发送的标头,您的 server.xml 配置需要包含以下内容:

<Valve
   className="org.apache.catalina.valves.RemoteIpValve"
   internalProxies=".*"
   protocolHeader="X-Forwarded-Proto"
   httpsServerPort="443"
   />

Spring 将根据 ServletRequest 确定绝对重定向地址,因此如果您使用的不是 443,请更改 httpsServerPort:

httpsServerPort是protocolHeader表示https协议时ServletRequest.getServerPort()返回的端口

于 2014-02-04T14:03:08.883 回答
14

如果是 Spring Boot 应用程序(我目前使用的是 2.0.0 版本),application.properties文件中的以下配置应该足够了:

server.tomcat.protocol-header=x-forwarded-proto

这在 AWS 上对我有用,前面有一个负载均衡器。

对于 Spring Boot < 2.0.0 它也应该可以工作(未测试)

于 2018-05-08T14:58:53.967 回答
4

我在使用 Google Kubernetes 背后的 Spring Boot 时遇到了同样的问题。将这两行添加到 application.properties 为我做了

server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto

来源:https ://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https

于 2018-12-12T20:50:31.760 回答
3

解决方案是两倍

(1) 应用程序.yml

server:
  use-forward-headers: true

(2) 在服务器中/etc/apache2/sites-enabled/oow.com-le-ssl.conf

RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443

(2.1)并启用了apache模块

sudo a2enmod headers

在这个这个的帮助下把它放在一起

于 2019-10-28T22:07:43.890 回答
2

我得到这个工作的一种方法是添加以下配置

<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint" >
    <form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?login_error=t" always-use-default-target="true" default-target-url="xxxxx" />
    <logout logout-url="/logout" logout-success-url="/logoutSuccess.jsf" />
    ...
</http>

不得不添加always-use-default-target="true"default-target-url="https://...."。这不是理想的方式,因为您需要在配置中对 url 进行硬编码。

于 2012-09-09T01:09:37.597 回答
0

在 web.xml 中使用以下代码行

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Login and Restricted Space URLs</web-resource-name>
    <url-pattern>/j_security_check</url-pattern>
    <url-pattern>/loginpage.rose</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

它被迫使用HTTPS。

于 2014-09-13T11:59:24.053 回答
0

我也面临着完全相同的问题,直到我得到正确的解决方案,我才通过 AJP 而不是 HTTP 将我的请求从代理服务器重定向到 tomcat 服务器。下面是我的apache配置

ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject
于 2014-03-15T06:36:49.143 回答
0

我在所有拦截 URL 上设置了 requires-channel="any"。这使它仍然可以在我不使用 SSL 的开发环境中工作。

<intercept-url pattern="/createUser" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>

然后,创建一个 apache 虚拟主机,将所有流量重定向到 HTTPS 版本。

<VirtualHost *:80>
  ServerName www.mywebsite.com
  Redirect permanent / https://www.mywebsite.com/
</VirtualHost>
于 2014-01-22T04:50:29.223 回答
0

就我而言,我必须删除该属性server.use-forward-headers=true

这是我的设置:

Digital Ocean LB --> 带有 Ingress 的 Kubernetes 集群 --> Spring boot Application

于 2019-01-06T21:45:54.853 回答
0

为我的 k8 到 spring boot 应用程序尝试了上面提到的一切,问题是 k8 是安全的,并且 ssl 是由位于入口前面的 SSL 加速器处理的。应用只收到http请求,spring security也转发到http,一直没找到。对我有用的解决方案:

nginx.ingress.kubernetes.io/proxy-redirect-from:http://$http_host/ nginx.ingress.kubernetes.io/proxy-redirect-to:https://$http_host/$namespace/helloworld-service/

于 2021-06-28T04:57:28.143 回答