在UserDetails实例中存储IP地址

时间:2014-04-10 10:20:36

标签: java spring spring-mvc spring-security

在我的网络应用程序中,我使用Spring Security和UserDetailsService实现进行身份验证。

现在我需要获取并存储当前会话的客户端IP地址,并且我希望将其存储在UserDetails实例中,以便在需要的地方检索它。

实现这一目标的正确方法是什么? Spring MVC / Security中是否有任何设施可以在服务层获取IP地址?

注意如果客户端未经过身份验证(记录访问尝试次数),我还需要知道IP地址

1 个答案:

答案 0 :(得分:4)

ip-address已存在于Authentication对象(而不是UserDetails)中。

您可以在Authentication对象和Web应用程序以及正确配置的Spring Security环境中调用getDetails(),这将为您提供一个WebAuthenticationDetails的实例,其中包含ip-address 。您可以调用getRemoteAddress方法获取地址。 (见javadoc)..

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
String ipAddress = details.getRemoteAddress();

沿着这些方向的东西,你可以把它放在一个实用工具方法或其他东西以获得ip-address。

显然,您希望记录身份验证尝试,这可以通过实现ApplicationListener轻松实现,并让其听取AbstractAuthenticationEvent。 Spring Security会针对每次身份验证尝试发出这些身份,并且还会将Authentication(包含IP地址)包含在其中。

public class AuthenticationAttemptLoggerListener implements ApplicationListener<AbstractAuthenticationEvent> {

    private final Logger logger = LoggerFactory.getLogger(AuthenticationAttemptLoggerListener.class)

    public void onApplicationEvent(AbstractAuthenticationEvent event) {
        Authentication auth = event.getAuthentication();
        WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
        String ipAddress = details.getRemoteAddress();

        if (event instanceof AbstractAuthenticationFailureEvent) {
            logger.warn("Unsuccesful authentication attemped from: {}", ipAddress);
        } else {
            logger.info("Succesful authentication attemped from: {}", ipAddress);
        }
    }

}

这样的东西应该捕获并记录所有内容。您可能想要查看所有available events