This commit is contained in:
2023-05-26 17:52:34 +08:00
parent dd1ab6e74e
commit 21632ef7cb
13 changed files with 96 additions and 18 deletions

View File

@ -15,6 +15,14 @@ import java.util.List;
*/
public class SecurityConstant {
/**
* 被挤下线
*/
public static final int HTTP_SQUEEZED_OFFLINE = 4011;
public static final int MAX_ERROR_COUNT = 5;
public static final String LOGOUT_URL = "/logout";
public static final String HAS_BEEN_PULLED_BLACK = "您的IP已经被系统拉黑";
@ -31,6 +39,7 @@ public class SecurityConstant {
public static final String REDIS_SECRET_KEY = "sys:secret:secret";
public static final String USER_DETAILS_REDIS_KEY = "user_details:";
public static final String ONLINE_USER_REDIS_KEY = "online_user:";
public static final String LOGGED_USER_REDIS_KEY = "logged_user:";
public static final String TOKEN_EXPIRE_TIME_KEY = ConfigConstant.SYS_CONFIG_KEY_PREFIX + "sys.token.expireTime";
/**
* 登录成功

View File

@ -23,6 +23,10 @@ public class LoginUser implements UserDetails {
private static final long serialVersionUID = 1L;
/**
* 设备号 暂用UUID
*/
private String deviceSn;
/**
* 用户ID
*/
@ -70,6 +74,14 @@ public class LoginUser implements UserDetails {
this.roles = roles;
}
public String getDeviceSn() {
return deviceSn;
}
public void setDeviceSn(String deviceSn) {
this.deviceSn = deviceSn;
}
public List<RoleDto> getRoles() {
return roles;
}

View File

@ -17,6 +17,11 @@ public class OnlineUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 设备号 暂用UUID
*/
private String deviceSn;
/**
* 登录账号
*/

View File

@ -3,6 +3,7 @@ package com.qiaoba.auth.filters;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.auth.constants.SecurityConstant;
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.web.utils.ResponseUtil;
@ -34,26 +35,31 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private final UserDetailsService userDetailsService;
private final OnlineUserService onlineUserService;
private final AuthConfigProperties authConfigProperties;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
if (authConfigProperties.getWhitelist().contains(request.getRequestURI())) {
chain.doFilter(request, response);
return;
}
// 取Header中的Token
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";
/* String username1 = "admin";
OnlineUser onlineUser = onlineUserService.selectByUsername(username1);
if (Objects.isNull(onlineUser)) {
// todo 返回401
ResponseUtil.response(response, "");
ResponseUtil.errorAuth(response, 4011, "暂无登录");
return;
}
}*/
// 续期有效期
onlineUserService.insert(onlineUser);
//onlineUserService.insert(onlineUser);
if (TokenUtil.validateToken(authToken)) {
String username = TokenUtil.getUserNameFromToken(authToken);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

View File

@ -1,9 +1,7 @@
package com.qiaoba.auth.handler;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.qiaoba.auth.constants.SecurityConstant;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.common.web.utils.ResponseUtil;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
@ -25,7 +23,6 @@ import java.io.IOException;
public class AccessDeniedHandler implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
AjaxResult result = AjaxResult.error(HttpStatus.HTTP_UNAUTHORIZED, SecurityConstant.ACCESS_DENIED);
ResponseUtil.response(response, JSONUtil.toJsonStr(result));
ResponseUtil.errorAuth(response, HttpStatus.HTTP_UNAUTHORIZED, SecurityConstant.ACCESS_DENIED);
}
}

View File

@ -1,6 +1,8 @@
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;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
@ -24,11 +26,13 @@ import java.io.IOException;
public class LogoutHandler implements LogoutSuccessHandler {
private final RedisService redisService;
private final OnlineUserService onlineUserService;
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
// 删除缓存中的用户信息
LoginUser user = (LoginUser) authentication.getPrincipal();
redisService.del(user.getUserId());
redisService.del(SecurityConstant.USER_DETAILS_REDIS_KEY + user.getUsername());
onlineUserService.deleteOne(user.getUsername(), user.getDeviceSn());
}
}

View File

@ -24,16 +24,25 @@ public interface OnlineUserService {
* 删除(强退)
*
* @param username 登录账号
* @param deviceSn 设备号
*/
void delete(String username);
void deleteOne(String username, String deviceSn);
/**
* 删除(强退)
*
* @param username 登录账号
*/
void deleteAll(String username);
/**
* 查询
*
* @param username 登录账号
* @param deviceSn deviceSn
* @return 在线用户
*/
OnlineUser selectByUsername(String username);
OnlineUser selectOne(String username, String deviceSn);
/**
* 批量查询
@ -42,4 +51,6 @@ public interface OnlineUserService {
* @return list
*/
List<OnlineUser> selectList(String username);
}

View File

@ -27,18 +27,26 @@ public class OnlineUserServiceImpl implements OnlineUserService {
@Override
public void insert(OnlineUser onlineUser) {
redisService.set(handleKey(onlineUser.getUsername()), onlineUser, TokenUtil.expireTime * 3600);
// key: username
// hashKey: deviceSn
// value: onlineUser
redisService.hSet(handleKey(onlineUser.getUsername()), onlineUser.getDeviceSn(), onlineUser, TokenUtil.expireTime * 3600);
}
@Override
public void delete(String username) {
public void deleteOne(String username, String deviceSn) {
redisService.hDel(handleKey(username), deviceSn);
}
@Override
public void deleteAll(String username) {
redisService.del(handleKey(username));
}
@Override
public OnlineUser selectByUsername(String username) {
if (redisService.hasKey(handleKey(username))) {
return redisService.getObject(handleKey(username), OnlineUser.class);
public OnlineUser selectOne(String username, String deviceSn) {
if (redisService.hHasKey(username, deviceSn)) {
return redisService.hGetObject(username, deviceSn, OnlineUser.class);
}
return null;
}

View File

@ -5,4 +5,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qiaoba.auth.filters.JwtAuthenticationTokenFilter,\
com.qiaoba.auth.advice.SecurityExceptionAdvice,\
com.qiaoba.auth.aspectj.DataScopeAspect,\
com.qiaoba.auth.service.impl.OnlineUserServiceImpl,\
com.qiaoba.auth.config.SpringSecurityConfig