first commit

This commit is contained in:
2023-05-28 00:14:58 +08:00
parent 21632ef7cb
commit b01b6df882
23 changed files with 243 additions and 57 deletions

View File

@ -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;

View File

@ -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;

View File

@ -26,6 +26,11 @@ public class SecurityUser implements Serializable {
*/
private String userId;
/**
* 设备SN
*/
private String deviceSn;
/**
* 部门ID
*/

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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();