在存在XFF标头的情况下,将"AuthenticationFailureBadCredentialsEvent"与远程地址相关联 [英] Associating an `AuthenticationFailureBadCredentialsEvent` with the remote address in the presence of XFF headers

查看:334
本文介绍了在存在XFF标头的情况下,将"AuthenticationFailureBadCredentialsEvent"与远程地址相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我写了这个...

So I wrote this ...

@Component
class AuthenticationFailureListener : ApplicationListener<AuthenticationFailureBadCredentialsEvent>{

    private val bruteForceProtection : BruteForceProtection

    @Inject
    constructor(bruteForceProtection: BruteForceProtection){
        this.bruteForceProtection = bruteForceProtection
    }

    override fun onApplicationEvent(event: AuthenticationFailureBadCredentialsEvent) {
        val webDetails = event.authentication.details as WebAuthenticationDetails
        val remoteAddress = webDetails.remoteAddress

        bruteForceProtection.recordFailedAttempt(remoteAddress)
    }
}

然后意识到我不知道在安全上下文中设置远程地址时,Spring是否使用X-Forwarded-For标头.

Then realised I have no idea if Spring accounts for X-Forwarded-For headers when setting the remote address in the security context.

是吗?

或者我如何将AuthenticationFailureBadCredentialsEvent与它源自的远程地址相关联?

Or how would I associate the AuthenticationFailureBadCredentialsEvent with the remote address it originated from?

推荐答案

来自

使用代理服务器时,确保已正确配置应用程序很重要.例如,许多应用程序将具有一个负载均衡器,该负载均衡器通过将请求转发到https://192.168.1:8080处的应用程序服务器来响应对https://example.com/的请求,如果没有适当的配置,则应用程序服务器将不知道负载均衡器是否存在并将该请求视为尽管https://192.168.1:8080是客户端请求的.

When using a proxy server it is important to ensure that you have configured your application properly. For example, many applications will have a load balancer that responds to request for https://example.com/ by forwarding the request to an application server at https://192.168.1:8080 Without proper configuration, the application server will not know that the load balancer exists and treat the request as though https://192.168.1:8080 was requested by the client.

要解决此问题,可以使用RFC 7239指定正在使用负载平衡器.为了使应用程序意识到这一点,您需要配置您的应用程序服务器以了解X-Forwarded标头.例如,Tomcat使用RemoteIpValve,而Jetty使用ForwardedRequestCustomizer.另外, Spring 4.3+及更高版本的用户可以使用ForwardedHeaderFilter.

To fix this you can use RFC 7239 to specify that a load balancer is being used. To make the application aware of this, you need to either configure your application server aware of the X-Forwarded headers. For example Tomcat uses the RemoteIpValve and Jetty uses ForwardedRequestCustomizer. Alternatively, Spring 4.3+ users can leverage ForwardedHeaderFilter.

Spring框架和Spring Security本身都不对X-Forwarded*标头做任何特殊的事情.

Neither Spring framework nor Spring Security itself do anything special about X-Forwarded* headers.

因此,我们应用这些信息的选项是:

So our options to apply such information are:

不幸的是, ForwardedHeaderFilter没有

Unfortunately ForwardedHeaderFilter does not inspect X-Forwarded-For header as of 5.1.7.RELEASE.

因此,剩下的选项是配置服务器.

So the option left is to configure server.

由于您使用的是tomcat,因此可以提供server.tomcat.remote-ip-header属性以将标头考虑在内.

Since you're using tomcat you can supply a server.tomcat.remote-ip-header property to take the header into account.

另请参见 application.yml :

server:
  tomcat:
    remote-ip-header: X-Forwarded-For

然后 getRemoteAddr 将返回X-Forwarded-For标头中存在的ip地址,该标头由

then getRemoteAddr will return the ip address present in X-Forwarded-For header which is used by WebAuthenticationDetails itself

WebAuthenticationDetails.java

WebAuthenticationDetails.java

public WebAuthenticationDetails(HttpServletRequest request) {
    this.remoteAddress = request.getRemoteAddr();

    HttpSession session = request.getSession(false);
    this.sessionId = (session != null) ? session.getId() : null;
}

这是一个简单的测试:

IpController.kt :

IpController.kt:

@RestController
class IpController {
    @GetMapping("/ip")
    fun getIp(request: HttpServletRequest) = mapOf("ip" to request.remoteAddr)
}

IpControllerTest.kt

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"])
    }
}

这篇关于在存在XFF标头的情况下,将"AuthenticationFailureBadCredentialsEvent"与远程地址相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆