让我们使用对记住我架构的理解。一个常见的要求是任何记住我的令牌都应该与创建它的用户的 IP 地址相关联。这为记住我功能增加了额外的安全性。为此,我们只需要实现一个自定义的 PersistentTokenRepository 接口。我们将进行的配置更改将说明如何配置自定义 RememberMeServices。在本节中,我们将查看本章源代码中包含的 IpAwarePersistentTokenRepository。 IpAwarePersistenTokenRepository 接口保证系列标识符在内部与当前用户的IP地址结合,而系列标识符在外部只包含标识符。这意味着无论何时查找或保存令牌,当前 IP 地址都用于查找或保存令牌。在以下代码片段中,您可以看到 IpAwarePersistentTokenRepository 的工作原理。如果您想深入挖掘,我们鼓励您查看本章包含的源代码。
查找 IP 地址的技巧是使用 Spring Security 的 RequestContextHolder。相关代码如下:
需要注意的是,为了使用
RequestContextHolder,你需要确保你已经设置了你的
web.xml 文件使用
RequestContextListener。我们已经为我们的示例代码执行了此设置。但是,当在外部应用程序中使用示例代码时,这可能很有用。参考Javadoc
IpAwarePersistentTokenRepository 了解如何设置的详细信息。
看看下面的代码片段:
我们可以在此方法的基础上强制保存的令牌在系列标识符中包含 IP 地址,如下所示:
您可以看到我们首先创建了一个新系列,并将 IP 地址连接到它上面。 tokenWithSeries 方法只是一个帮助器,它创建一个具有所有相同值的新标记,除了一个新系列。然后,我们将带有包含 IP 地址的系列标识符的新令牌提交给 delegateRepsository,这是 PersistentTokenRepository 的原始实现。
每当查找令牌时,我们都要求将当前用户的 IP 地址附加到系列标识符中。这意味着用户无法为具有不同 IP 地址的用户获取令牌:
代码的其余部分非常相似。在内部,我们构造要附加到 IP 地址的系列标识符,而在外部,我们只显示原始系列标识符。通过这样做,我们强制执行只有创建记住我令牌的用户才能使用它的约束。
让我们回顾一下本章的 IpAwarePersistentTokenRepository 示例代码中包含的 Spring 配置。在以下代码片段中,我们首先创建包装新 JpaPersistentTokenRepository 声明的 IpAwarePersistentTokenRepository 声明。然后我们通过实例化一个 OrderedRequestContextFilter 接口来初始化一个 RequestContextFilter 类:
为了让 Spring Security 使用我们自定义的 RememberMeServices,我们需要更新我们的安全配置以指向它。继续对 SecurityConfig.java 进行以下更新:
现在,继续并启动应用程序。您可以使用第二台计算机和 Firebug 等插件来操作您的记住我的 cookie。如果您尝试在另一台计算机上使用来自一台计算机的 remember-me cookie,Spring Security 现在将忽略 remember-me 请求并删除关联的 cookie。
您的代码应如下所示
chapter07.07-日历。
请注意,如果用户位于共享或负载平衡的网络基础架构(例如多 WAN 公司环境)后面,则基于 IP 的记住我令牌可能会出现意外行为。然而,在大多数情况下,向记住我功能添加 IP 地址为有用的用户功能提供了额外的、受欢迎的安全层。