【发布时间】:2018-05-25 21:15:43
【问题描述】:
如何继续侦听端口 80 (http),但在登录页面的 Spring Boot 应用程序中将 302 重定向发送到端口 443 (https)。我需要这个,因为我的应用程序位于终止 SSL 证书并向我的应用程序发送 http 请求的 F5 BigIP 代理后面,目前,我看到了这种行为:
这是当前有缺陷的流程:
- 客户端请求https://myapp.example.com
- F5 BigIP 转换为 (HTTP)myapp.example.com
我的 Spring Boot 应用程序重定向到 (HTTP)myapp.example.com/login 作为客户端的 302 指令
客户端请求 (HTTP)myapp.example.com/login
-
F5 BigIP 拒绝 HTTP 请求
想要的流量:
-
我的 Spring Boot 应用程序将重定向到 (HTTPS)myapp.example.com/login 作为 302 发送到客户端 (Location=(HTTPS)myapp.example.com/login)
李> F5 BigIP 转换为 (HTTP)myapp.example.com/login
- 我的 Spring Boot 应用程序响应登录页面,一切都是 Honky Dory
我使用的是 Spring Boot 1.2.8 版,我的应用程序位于 F5 BigIp 负载均衡器后面。 BigIP 终止 SSL 证书并将所有 HTTPS 请求重定向到仅在端口 80 (http) 上侦听的 Spring Boot 应用程序。
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/error", "/js/**", "/css/**", "/img/**", "/help", "/favicon.ico").permitAll()
.anyRequest().hasAuthority("USER")
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login-error")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout()
.permitAll();
}
}
我按照 //docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-enable-https 文档添加:
这些application.properties:
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
server.tomcat.internal-proxies=x\.x\.x\.x|x\.x\.x\.x (I tested without this parameter as well)
顺便说一句:使用 http.requiresChannel().anyRequest().requiresSecure() 强制使用 HTTPS;在这种情况下不起作用,因为我需要来自 HTTP 上的 F5 BigIp 的第二个请求才能工作,使用此设置将循环整个重定向舞蹈。
我需要配置我的应用程序以将由 BigIP 代理的客户端请求 https://myApp.example.com 重定向到 http://myApp.example.com/ 致https://myApp.example.com/login,以便 F5 BigIP 接受。
这是 curl 请求的结果: curl -L -b -vk --url https://myApp.example.com --verbose -vs > curl-output.txt 2>&1
STATE: INIT => CONNECT handle 0x440f160; line 1392 (connection #-5000)
* Rebuilt URL to: https://myApp.example.com/
* Added connection 0. The cache now contains 1 members
* STATE: CONNECT => WAITRESOLVE handle 0x440f160; line 1428 (connection #0)
* Trying XXX.XX.XX.XXX...
…
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x440f160; line 1596 (connection #0)
} [5 bytes data]
> GET / HTTP/1.1
> Host: myApp.example.com
> User-Agent: curl/7.58.0
> Accept: */*
…
< HTTP/1.1 302
…
< X-XSS-Protection: 1; mode=block
* Added cookie JSESSIONID="4CE1A6F2AB684C6E01774E5289AF2AC0" for domain myApp.example.com, path /, expire 0
< Set-Cookie: JSESSIONID=4CE1A6F2AB684C6E01774E5289AF2AC0;path=/;HttpOnly
****< Location: http://myApp.example.com/login <- this needs to be HTTPS****
< Date: Wed, 09 May 2018 22:30:36 GMT
…
* Connection #0 to host myApp.example.com left intact
* Issue another request to this URL: 'http://myApp.example.com/login' <- this needs to be HTTPS
* STATE: PERFORM => CONNECT handle 0x440f160; line 1949 (connection #-5000)
* Added connection 1. The cache now contains 2 members
* STATE: CONNECT => WAITRESOLVE handle 0x440f160; line 1428 (connection #1)
* Trying XXX.XX.XX.XXX...
* TCP_NODELAY set
* STATE: WAITRESOLVE => WAITCONNECT handle 0x440f160; line 1509 (connection #1)
* connect to XXX.XX.XX.XXX port 80 failed: Connection refused
* Failed to connect to myApp.example.com port 80: Connection refused<= Not the result we want
* Closing connection 1
【问题讨论】:
-
你说你想做一个 HTTPS 重定向,然后在第 3 步你写:“我的 Spring Boot 应用程序重定向到 (http)myapp.example.com/login 作为客户端的 302 指令” .那么您的应用程序是否在 302 重定向的 Location 标头中放置了 HTTPS 或 HTTP 链接?您没有显示生成重定向的代码部分。您需要在此处修复 URL。
-
感谢您这么快回来。我在问题中添加了 sn-p。
-
这(我不使用 Spring Boot)真的会生成带有 Location 标头的 302 HTTP 重定向吗?看起来不像,但我又不使用 Spring Boot。
-
是的,确实如此,您可以在 curl 跟踪中看到它。
-
是的,但是代码对我来说不是很清楚(同样,不是 Spring Boot 的用户)。因此,似乎重定向本身是由您的框架而不是您自己完成的,因此您可能需要了解有关框架的更多信息以说服它这样做或能够覆盖它。
标签: spring-boot ssl spring-security f5