最新稳定版请使用Spring Session 3.5.3spring-doc.cadn.net.cn

春季课程 - 通过用户名查找

本指南介绍了如何使用Spring Session按用户名查找会话。spring-doc.cadn.net.cn

你可以在findbyusername应用中找到完成的指南。

假设

本指南假设你已经通过 Redis 内置配置支持为应用添加了 Spring Session。 指南还假设你已经为申请应用应用了Spring Security。 不过,本指南较为通用,可以以最小改动应用于任何技术,相关内容我们稍后会讨论。spring-doc.cadn.net.cn

如果你需要学习如何将春季会话添加到你的项目中,请查看示例和指南列表

关于样本

我们的示例利用此功能使可能被攻破的用户会话失效。 请考虑以下情景:spring-doc.cadn.net.cn

如果我们能让用户在任何他们认证的设备上取消图书馆会话,那不是很好吗? 这个示例展示了这是可能的。spring-doc.cadn.net.cn

FindByIndexNameSessionRepository

要通过用户名查找用户,首先必须选择一个会话仓库实现FindByIndexNameSessionRepository. 我们的示例应用假设 Redis 支持已经设置好,所以我们已经准备好了。spring-doc.cadn.net.cn

用户名映射

FindByIndexNameSessionRepository如果开发者指示 Spring Session 与会期. 你可以通过确保会话属性带有名称来实现FindByUsernameSessionRepository.PRINCIPAL_NAME_INDEX_NAME该用户名被填充。spring-doc.cadn.net.cn

一般来说,用户认证后,你可以立即使用以下代码进行:spring-doc.cadn.net.cn

String username = "username";
this.session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);

使用 Spring Security 映射用户名称

由于我们使用Spring Security,用户名会自动被索引。 这意味着我们无需采取任何步骤来确保用户名被索引。spring-doc.cadn.net.cn

向会话添加额外数据

为会话添加额外信息(如IP地址、浏览器、位置及其他细节)可能会很方便。 这样做让用户更容易知道自己正在看的是哪个会话。spring-doc.cadn.net.cn

为此,确定你想使用哪个会话属性以及你希望提供哪些信息。 然后创建一个 Java 豆,作为会话属性添加。 例如,我们的示例应用包含会话的位置和访问类型,如下列表所示:spring-doc.cadn.net.cn

public class SessionDetails implements Serializable {

	private String location;

	private String accessType;

	public String getLocation() {
		return this.location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public String getAccessType() {
		return this.accessType;
	}

	public void setAccessType(String accessType) {
		this.accessType = accessType;
	}

	private static final long serialVersionUID = 8850489178248613501L;

}

然后我们用SessionDetailsFilter,如下示例所示:spring-doc.cadn.net.cn

@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
		throws IOException, ServletException {
	chain.doFilter(request, response);

	HttpSession session = request.getSession(false);
	if (session != null) {
		String remoteAddr = getRemoteAddress(request);
		String geoLocation = getGeoLocation(remoteAddr);

		SessionDetails details = new SessionDetails();
		details.setAccessType(request.getHeader("User-Agent"));
		details.setLocation(remoteAddr + " " + geoLocation);

		session.setAttribute("SESSION_DETAILS", details);
	}
}

我们获取所需的信息,然后设置会议详情作为会期. 当我们取回会期通过用户名,我们可以利用会话访问会议详情就像我们对待其他会话属性一样。spring-doc.cadn.net.cn

你可能会好奇为什么春季课程不提供会议详情开箱即用的功能。 我们有两个原因。 第一个原因是应用程序自己实现这一点非常简单。 第二个原因是会话中填充的信息(以及这些信息更新的频率)高度依赖于应用程序。

为特定用户寻找会话

我们现在可以找到特定用户的所有会话。 以下示例展示了如何实现:spring-doc.cadn.net.cn

@Autowired
FindByIndexNameSessionRepository<? extends Session> sessions;

@RequestMapping("/")
public String index(Principal principal, Model model) {
	Collection<? extends Session> usersSessions = this.sessions.findByPrincipalName(principal.getName()).values();
	model.addAttribute("sessions", usersSessions);
	return "index";
}

在我们的实例中,我们找到了当前登录用户的所有会话。 不过,你可以修改管理员的表单,指定要查找哪个用户。spring-doc.cadn.net.cn

Findbyusername示例应用

本节描述如何使用Findbyusername示例应用。spring-doc.cadn.net.cn

运行Findbyusername示例应用

您可以通过获取源代码并调用以下命令来运行示例:spring-doc.cadn.net.cn

$ ./gradlew :spring-session-sample-boot-findbyusername:bootRun
为了让样本正常工作,你必须在localhost上安装Redis 2.8+,并用默认端口(6379)运行。 或者,你也可以更新RedisConnection工厂指向一个Redis服务器。 另一个选择是用 Docker 在 localhost 上运行 Redis。 详见 Docker Redis 仓库中的详细说明。

你现在应该可以在localhost:8080/访问该应用了spring-doc.cadn.net.cn

探索安全示例应用

你现在可以尝试使用这个应用程序了。请输入以下方式登录:spring-doc.cadn.net.cn

现在点击登录按钮。 你现在应该会看到一条消息,表示你已经登录了之前输入的用户。 你还应该会看到当前登录用户的活跃会话列表。spring-doc.cadn.net.cn

您可以通过以下作模拟我们在“关于样本”部分讨论的流程:spring-doc.cadn.net.cn