✨ 新增管理员代登录功能
This commit is contained in:
@@ -101,7 +101,7 @@ public class LogAspect
|
||||
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
|
||||
if (loginUser != null)
|
||||
{
|
||||
operLog.setOperName(loginUser.getUsername());
|
||||
operLog.setOperName(loginUser.isImpersonating() ? loginUser.getImpersonatorName() : loginUser.getUsername());
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
if (StringUtils.isNotNull(currentUser) && StringUtils.isNotNull(currentUser.getDept()))
|
||||
{
|
||||
@@ -122,6 +122,11 @@ public class LogAspect
|
||||
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
|
||||
// 处理设置注解上的参数
|
||||
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
|
||||
if (loginUser != null && loginUser.isImpersonating())
|
||||
{
|
||||
String target = "代登录目标=" + loginUser.getUsername() + "(ID=" + loginUser.getUserId() + "); ";
|
||||
operLog.setOperParam(StringUtils.substring(target + StringUtils.defaultString(operLog.getOperParam()), 0, PARAM_MAX_LENGTH));
|
||||
}
|
||||
// 设置消耗时间
|
||||
operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
|
||||
// 保存数据库
|
||||
|
||||
+48
-1
@@ -11,10 +11,16 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.bms.common.core.domain.model.LoginUser;
|
||||
import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.framework.web.service.TokenService;
|
||||
import com.bms.framework.manager.AsyncManager;
|
||||
import com.bms.framework.manager.factory.AsyncFactory;
|
||||
import com.bms.system.domain.SysOperLog;
|
||||
import com.bms.common.utils.ip.IpUtils;
|
||||
|
||||
/**
|
||||
* token过滤器 验证token有效性
|
||||
@@ -24,6 +30,7 @@ import com.bms.framework.web.service.TokenService;
|
||||
@Component
|
||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@@ -39,6 +46,46 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
|
||||
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
if (loginUser == null || !loginUser.isImpersonating())
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
long started = System.currentTimeMillis();
|
||||
boolean failed = false;
|
||||
try
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
catch (IOException | ServletException | RuntimeException e)
|
||||
{
|
||||
failed = true;
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 记录所有代登录请求的真实操作人和目标账号,不记录令牌、请求参数或响应正文。
|
||||
try
|
||||
{
|
||||
SysOperLog accessLog = new SysOperLog();
|
||||
accessLog.setTitle("代登录访问");
|
||||
accessLog.setBusinessType(0);
|
||||
accessLog.setOperatorType(1);
|
||||
accessLog.setOperName(loginUser.getImpersonatorName());
|
||||
accessLog.setOperIp(IpUtils.getIpAddr(request));
|
||||
accessLog.setOperUrl(StringUtils.substring(request.getRequestURI(), 0, 255));
|
||||
accessLog.setRequestMethod(request.getMethod());
|
||||
accessLog.setMethod("impersonation");
|
||||
accessLog.setOperParam("实际管理员ID=" + loginUser.getImpersonatorId() + ", 目标用户="
|
||||
+ loginUser.getUsername() + "(ID=" + loginUser.getUserId() + "), HTTP状态=" + response.getStatus());
|
||||
accessLog.setStatus(failed || response.getStatus() >= 400 ? 1 : 0);
|
||||
accessLog.setCostTime(System.currentTimeMillis() - started);
|
||||
AsyncManager.me().execute(AsyncFactory.recordOper(accessLog));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("记录代登录访问日志失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-2
@@ -74,6 +74,19 @@ public class TokenService
|
||||
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
|
||||
String userKey = getTokenKey(uuid);
|
||||
LoginUser user = redisCache.getCacheObject(userKey);
|
||||
if (user != null && user.isImpersonating())
|
||||
{
|
||||
LoginUser operator = StringUtils.isEmpty(user.getImpersonatorToken()) ? null
|
||||
: redisCache.getCacheObject(getTokenKey(user.getImpersonatorToken()));
|
||||
if (user.getImpersonationExpireTime() == null
|
||||
|| user.getImpersonationExpireTime() <= System.currentTimeMillis()
|
||||
|| operator == null || operator.isImpersonating()
|
||||
|| !user.getImpersonatorId().equals(operator.getUserId()))
|
||||
{
|
||||
redisCache.deleteObject(userKey);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -150,10 +163,29 @@ public class TokenService
|
||||
public void refreshToken(LoginUser loginUser)
|
||||
{
|
||||
loginUser.setLoginTime(System.currentTimeMillis());
|
||||
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
|
||||
long expiry = loginUser.getLoginTime() + expireTime * MILLIS_MINUTE;
|
||||
if (loginUser.isImpersonating())
|
||||
{
|
||||
if (loginUser.getImpersonationExpireTime() == null
|
||||
|| loginUser.getImpersonationExpireTime() <= loginUser.getLoginTime())
|
||||
{
|
||||
delLoginUser(loginUser.getToken());
|
||||
return;
|
||||
}
|
||||
expiry = Math.min(expiry, loginUser.getImpersonationExpireTime());
|
||||
}
|
||||
loginUser.setExpireTime(expiry);
|
||||
// 根据uuid将loginUser缓存
|
||||
String userKey = getTokenKey(loginUser.getToken());
|
||||
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
|
||||
if (loginUser.isImpersonating())
|
||||
{
|
||||
int ttlSeconds = (int) Math.max(1, (expiry - loginUser.getLoginTime() + 999) / 1000);
|
||||
redisCache.setCacheObject(userKey, loginUser, ttlSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
else
|
||||
{
|
||||
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user