1. 概述
本教程,我们将重点介绍如何在Spring Security和Spring MVC中以编程方式手动认证用户,即自定义登录验证。
2. Spring Security
简单来说,Spring Security在ThreadLocal
中保存有每个认证用户的信息 —— 即Authentication对象。
为了构造和设置这个Authentication
对象,我们需要使用与Spring Security一样的实现方法。
为此,让我们手动触发身份认证,然后将认证结果 —— Authentication
对象设置到Spring Security当前持有的SecurityContext
中,以保存当前登录的用户信息:
UsernamePasswordAuthenticationToken authReq
= new UsernamePasswordAuthenticationToken(user, pass);
Authentication auth = authManager.authenticate(authReq);
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
完成设置后,我们现在可以通过securityContext.getAuthentication().isAuthenticated()
方法,判断当前用户是否完成认证了。
3. Spring MVC
默认情况下,Spring Security会添加一个SecurityContextPersistenceFilter
过滤器,作用是持久化Security Context。
它转而将Security Context的持久化委托给SecurityContextRepository
实例,默认实现类为 HttpSessionSecurityContextRepository
,即将SecurityContext持久化到HttpSession中。
因此,为了仅在第一次登录时设置Authentication
,从而使后续请求均可用,我们需要手动将包含Authentication
的SecurityContext
设置到HTTP Session中:
public void login(HttpServletRequest req, String user, String pass) {
UsernamePasswordAuthenticationToken authReq
= new UsernamePasswordAuthenticationToken(user, pass);
Authentication auth = authManager.authenticate(authReq);
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
HttpSession session = req.getSession(true);
session.setAttribute(SPRING_SECURITY_CONTEXT_KEY, sc);
}
SPRING_SECURITY_CONTEXT_KEY
是静态导入的HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
需要说明的是,我们不能直接使用HttpSessionSecurityContextRepository
,因为它是配合SecurityContextPersistenceFilter
一起使用。
4. 总结
本快速入门教程中,我们介绍了如何在Spring Security context中手动设置Authentication,并以例子演示如何实现。
惯例,本教程完整源代码可从GitHub上获取。