first commit
This commit is contained in:
@ -64,7 +64,8 @@ public class LoginUser implements UserDetails {
|
||||
public LoginUser() {
|
||||
}
|
||||
|
||||
public LoginUser(String userId, String deptId, String username, String nickname, List<RoleDto> roles, List<String> roleKeys, Set<String> permissions) {
|
||||
public LoginUser(String deviceSn, String userId, String deptId, String username, String nickname, List<RoleDto> roles, List<String> roleKeys, Set<String> permissions) {
|
||||
this.deviceSn = deviceSn;
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.username = username;
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.qiaoba.auth.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@ -13,6 +15,8 @@ import java.util.Date;
|
||||
* @since 2023/5/25 17:05
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OnlineUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -26,6 +26,11 @@ public class SecurityUser implements Serializable {
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 设备SN
|
||||
*/
|
||||
private String deviceSn;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
|
@ -6,6 +6,7 @@ import com.qiaoba.auth.entity.OnlineUser;
|
||||
import com.qiaoba.auth.properties.AuthConfigProperties;
|
||||
import com.qiaoba.auth.service.OnlineUserService;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import com.qiaoba.common.web.utils.ResponseUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@ -33,6 +34,7 @@ import java.util.Objects;
|
||||
@RequiredArgsConstructor
|
||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||
|
||||
private final RedisService redisService;
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final AuthConfigProperties authConfigProperties;
|
||||
@ -51,24 +53,28 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||
String authHeader = request.getHeader(SecurityConstant.TOKEN_HEADER);
|
||||
if (StrUtil.isNotBlank(authHeader) && authHeader.startsWith(SecurityConstant.TOKEN_HEAD)) {
|
||||
String authToken = authHeader.substring(SecurityConstant.TOKEN_HEAD.length());
|
||||
// todo
|
||||
/* String username1 = "admin";
|
||||
OnlineUser onlineUser = onlineUserService.selectByUsername(username1);
|
||||
if (Objects.isNull(onlineUser)) {
|
||||
ResponseUtil.errorAuth(response, 4011, "暂无登录");
|
||||
return;
|
||||
}*/
|
||||
// 续期有效期
|
||||
//onlineUserService.insert(onlineUser);
|
||||
if (TokenUtil.validateToken(authToken)) {
|
||||
String username = TokenUtil.getUserNameFromToken(authToken);
|
||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
String username = authToken.split(":")[0];
|
||||
String deviceSn = authToken.split(":")[1];
|
||||
|
||||
if (!"/logout".equals(request.getRequestURI())) {
|
||||
if (redisService.hasKey(SecurityConstant.LOGGED_USER_REDIS_KEY + username)) {
|
||||
if (!onlineUserService.checkIsLastLogged(username, deviceSn)) {
|
||||
ResponseUtil.errorAuth(response, 4012, "被挤下线");
|
||||
onlineUserService.deleteOne(username, deviceSn);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ResponseUtil.errorAuth(response, 4011, "登陆过期");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.qiaoba.auth.handler;
|
||||
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.entity.LoginUser;
|
||||
import com.qiaoba.auth.service.OnlineUserService;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
@ -32,7 +31,6 @@ public class LogoutHandler implements LogoutSuccessHandler {
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
||||
// 删除缓存中的用户信息
|
||||
LoginUser user = (LoginUser) authentication.getPrincipal();
|
||||
redisService.del(SecurityConstant.USER_DETAILS_REDIS_KEY + user.getUsername());
|
||||
onlineUserService.deleteOne(user.getUsername(), user.getDeviceSn());
|
||||
}
|
||||
}
|
||||
|
@ -52,5 +52,12 @@ public interface OnlineUserService {
|
||||
*/
|
||||
List<OnlineUser> selectList(String username);
|
||||
|
||||
|
||||
/**
|
||||
* 检查设备是否是最新登陆的设备
|
||||
*
|
||||
* @param username username
|
||||
* @param deviceSn deviceSn
|
||||
* @return 结果
|
||||
*/
|
||||
Boolean checkIsLastLogged(String username, String deviceSn);
|
||||
}
|
||||
|
@ -1,15 +1,18 @@
|
||||
package com.qiaoba.auth.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.api.auth.service.SysUserDetailsApiService;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.entity.OnlineUser;
|
||||
import com.qiaoba.auth.service.OnlineUserService;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import com.qiaoba.common.base.constants.BaseConstant;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -24,29 +27,34 @@ import java.util.List;
|
||||
public class OnlineUserServiceImpl implements OnlineUserService {
|
||||
|
||||
private final RedisService redisService;
|
||||
private final SysUserDetailsApiService sysUserDetailsApiService;
|
||||
|
||||
@Override
|
||||
public void insert(OnlineUser onlineUser) {
|
||||
// key: username
|
||||
// hashKey: deviceSn
|
||||
// key: username:deviceSn
|
||||
// value: onlineUser
|
||||
redisService.hSet(handleKey(onlineUser.getUsername()), onlineUser.getDeviceSn(), onlineUser, TokenUtil.expireTime * 3600);
|
||||
redisService.set(handleKey(onlineUser.getUsername(), onlineUser.getDeviceSn()), onlineUser, TokenUtil.expireTime * 3600);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteOne(String username, String deviceSn) {
|
||||
redisService.hDel(handleKey(username), deviceSn);
|
||||
if (deviceSn.equals(redisService.get(SecurityConstant.LOGGED_USER_REDIS_KEY + username))) {
|
||||
redisService.del(SecurityConstant.LOGGED_USER_REDIS_KEY + username);
|
||||
}
|
||||
sysUserDetailsApiService.deleteCache(username, deviceSn);
|
||||
redisService.del(handleKey(username, deviceSn));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(String username) {
|
||||
redisService.del(handleKey(username));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public OnlineUser selectOne(String username, String deviceSn) {
|
||||
if (redisService.hHasKey(username, deviceSn)) {
|
||||
return redisService.hGetObject(username, deviceSn, OnlineUser.class);
|
||||
String key = handleKey(username, deviceSn);
|
||||
if (redisService.hasKey(key)) {
|
||||
return redisService.getObject(key, OnlineUser.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -58,13 +66,22 @@ public class OnlineUserServiceImpl implements OnlineUserService {
|
||||
key = key + username + "*";
|
||||
}
|
||||
|
||||
if (redisService.hasKey(key)) {
|
||||
return redisService.getObjectList(key, OnlineUser.class);
|
||||
List<OnlineUser> users = new ArrayList<>();
|
||||
Collection<String> keys = redisService.getKeys(key);
|
||||
for (String temp : keys) {
|
||||
temp = temp.replace("tenant_1:", "");
|
||||
users.add(redisService.getObject(temp, OnlineUser.class));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
return users;
|
||||
}
|
||||
|
||||
private String handleKey(String key) {
|
||||
return SecurityConstant.ONLINE_USER_REDIS_KEY + key;
|
||||
@Override
|
||||
public Boolean checkIsLastLogged(String username, String deviceSn) {
|
||||
String loggedDevice = redisService.get(SecurityConstant.LOGGED_USER_REDIS_KEY + username).toString();
|
||||
return deviceSn.equals(loggedDevice);
|
||||
}
|
||||
|
||||
private String handleKey(String key, String deviceSn) {
|
||||
return SecurityConstant.ONLINE_USER_REDIS_KEY + key + BaseConstant.COLON_JOIN_STR + deviceSn;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class TokenUtil {
|
||||
* jwt 加解密密钥,第一次项目启动时创建随机数
|
||||
*/
|
||||
public static String secret;
|
||||
public static Integer expireTime = 1;
|
||||
public static Integer expireTime = 72;
|
||||
|
||||
public static String generateToken(String username) {
|
||||
DateTime now = DateTime.now();
|
||||
|
Reference in New Issue
Block a user