我有一个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?
答案 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
答案 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
答案 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/