使用Spring Security进行HTTPS登录会重定向到HTTP

时间:2012-04-30 15:10:15

标签: spring ssl https spring-security tomcat6

我有一个Spring网络应用程序,使用Spring Security保护,在EC2上运行。在EC2实例前面是一个带有SSL证书的Elastic Load Balancer(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?

  • Tomcat 6
  • Spring Security 3.0.x

10 个答案:

答案 0 :(得分:21)

您的弹簧配置应与所使用的协议无关。如果您使用“需要通道”之类的东西,迟早会遇到问题,特别是如果您想将相同的应用程序部署到没有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()   协议

答案 1 :(得分:7)

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

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

这适用于AWS,前端有负载均衡器。

对于Spring Boot&lt; 2.0.0它也应该工作(未测试)

答案 2 :(得分: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://...."。不是理想的方式,因为您需要在配置中对网址进行硬编码。

答案 3 :(得分:0)

我在所有拦截网址上设置了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>

答案 4 :(得分:0)

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

ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject

答案 5 :(得分: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。

答案 6 :(得分:0)

我在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

答案 7 :(得分:0)

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

这是我的设置:

Digital Ocean LB->具有Ingress的Kubernetes集群-> Spring Boot应用程序

答案 8 :(得分:0)

解决方案是两倍

(1)application.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

借助thisthis

答案 9 :(得分:0)

为我的 k8 到 spring 启动应用程序尝试了上面提到的所有内容,问题是 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/