С Spring Security # 15.4 Конфигурация прокси-сервера :
При использовании прокси-сервера важно убедиться, что вы правильно настроили свое приложение. Например, многие приложения будут иметь балансировщик нагрузки, который отвечает на запрос https://example.com/
путем пересылки запроса на сервер приложений на https://192.168.1:8080
. Без правильной конфигурации сервер приложений не будет знать, что существует балансировщик нагрузки, и будет обрабатывать запрос как хотя https://192.168.1:8080
был запрошен клиентом.
Чтобы исправить это, вы можете использовать RFC 7239, чтобы указать, что используется балансировщик нагрузки. Чтобы приложение знало об этом, вам нужно либо настроить свой сервер приложений на X-Forwarded
заголовки . Например, Tomcat использует RemoteIpValve
, а Jetty использует ForwardedRequestCustomizer
. В качестве альтернативы пользователи Spring 4.3+ могут использовать ForwardedHeaderFilter
.
.
Ни среда Spring, ни сама Spring Security не делают ничего особенного в X-Forwarded*
заголовках.
Таким образом, наши варианты применения такой информации:
К сожалению ForwardedHeaderFilter
не проверяет X-Forwarded-For
заголовок с 5.1.7.RELEASE
.
Таким образом, оставленный вариант - настроить сервер.
Поскольку вы используете tomcat, вы можете указать свойство server.tomcat.remote-ip-header
, чтобы учесть заголовок.
См. Также ServerProperties
application.yml
server:
tomcat:
remote-ip-header: X-Forwarded-For
затем getRemoteAddr
вернет IP-адрес, присутствующий в заголовке X-Forwarded-For
, который используется WebAuthenticationDetails
сам
WebAuthenticationDetails.java
public WebAuthenticationDetails(HttpServletRequest request) {
this.remoteAddress = request.getRemoteAddr();
HttpSession session = request.getSession(false);
this.sessionId = (session != null) ? session.getId() : null;
}
Вот тест простой тест:
IpController.kt
@RestController
class IpController {
@GetMapping("/ip")
fun getIp(request: HttpServletRequest) = mapOf("ip" to request.remoteAddr)
}
IpControllerTest.kt
@SpringBootTest(properties = ["server.tomcat.remote-ip-header=X-Forwarded-For"],
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class IpControllerTest {
@Autowired
private lateinit var testRestTemplate: TestRestTemplate
@Test
fun `uses ip from x-forwarded-for`() {
val httpHeaders = HttpHeaders()
httpHeaders["X-Forwarded-For"] = "8.8.8.8"
val httpEntity = HttpEntity<Any>(httpHeaders)
val map = testRestTemplate.exchange<Map<String, *>>("/ip", HttpMethod.GET, httpEntity)
.body!!
assertEquals("8.8.8.8", map["ip"])
}
}