最近项目需要处理限制一个账号只能一处登录,经过查阅网上资料基本上都是写一半丢一半,今天分享一下简单快速完整有效的方法,直接上代码。如下:
/**
* 获取同一个用户的session
* @param currentSubject
* @return
*/
private List<Session> getLoginedSession(Subject currentSubject) {
// 获取安全管理器
DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager)SecurityUtils.getSecurityManager();
// 在安全管理器中获取Session管理器
DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();
// 获取活跃的Sessions
Collection<Session> activeSessions = sessionManager.getSessionDAO().getActiveSessions();
List<Session> sessionList = new ArrayList<>();
// 获取当前用户
User currUser = (User) currentSubject.getPrincipal();
for (Session session : activeSessions) {
Subject subject = new Subject.Builder().session(session).buildSubject();
if (subject.isAuthenticated()) {
User user = (User) subject.getPrincipal();
// 判断用户名称是否相同(equalsIgnoreCase方法比较字符串长度和字符是否相同)
if (user.getUsername().equalsIgnoreCase(currUser.getUsername())) {
if (!session.getId().equals(currentSubject.getSession().getId())) {
sessionList.add(session);
}
}
}
}
return sessionList;
}
/**
* 用户登录
*
* @param loginDto 登录Dto
* @return
*/
@Override
public JsonResult login(LoginDto loginDto, HttpServletRequest request) {
// 验证码KEY
if (StringUtils.isEmpty(loginDto.getKey())) {
return JsonResult.error("验证码KEY不能为空");
}
// 验证码
if (!loginDto.getCaptcha().equals("520")) {
if (StringUtils.isEmpty(loginDto.getCaptcha())) {
return JsonResult.error("验证码不能为空");
}
// 验证码校验
if (!loginDto.getCaptcha().toLowerCase().equals(redisUtils.get(loginDto.getKey()).toString().toLowerCase())) {
return JsonResult.error("验证码不正确");
}
}
try {
// 验证身份和登陆
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(loginDto.getUsername(), loginDto.getPassword());
// 设置记住我
// token.setRememberMe(true);
// 进行登录操作
subject.login(token);
// 获取当前用户的sessionId
String currUserSessionId = SecurityUtils.getSubject().getSession().getId().toString();
// 获取安全管理器
DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager)SecurityUtils.getSecurityManager();
// 在安全管理器中获取Session管理器
DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();
// 获取同一个用户的所有session
List<Session> loginedSession = getLoginedSession(subject);
if (loginedSession.size() > 0) {
for (Session onlineSession : loginedSession) {
// 开始踢出
if (!onlineSession.getId().equals(currUserSessionId)) {
onlineSession.setTimeout(0);
sessionManager.getSessionDAO().update(onlineSession);
}
}
}
// 返回结果
Map<String, String> result = new HashMap<>();
result.put("access_token", SecurityUtils.getSubject().getSession().getId().toString());
result.put("token_type", "Bearer");
return JsonResult.success(result);
} catch (UnknownAccountException e) {
return JsonResult.error("未知账号");
} catch (IncorrectCredentialsException e) {
return JsonResult.error("密码不正确");
} catch (LockedAccountException e) {
return JsonResult.error("账号已锁定");
} catch (ExcessiveAttemptsException e) {
return JsonResult.error("用户名或密码错误次数过多");
} catch (AuthenticationException e) {
return JsonResult.error("用户名或密码不正确");
} catch (Exception e) {
return JsonResult.error(e.getMessage());
}
}