1. 修复 request body 缓存的 bug

2. 进一步完善 api 访问日志的实现
This commit is contained in:
YunaiV
2021-02-26 20:42:14 +08:00
parent 70af2bc78c
commit 7a87fdbd79
19 changed files with 306 additions and 41 deletions

View File

@@ -1,17 +1,13 @@
package cn.iocoder.dashboard.framework.security.core.filter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.dashboard.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService;
import cn.iocoder.dashboard.util.servlet.ServletUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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;
@@ -42,7 +38,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@SuppressWarnings("NullableProblems")
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String token = SecurityUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
if (StrUtil.isNotEmpty(token)) {
try {
// 验证 token 有效性
@@ -53,7 +49,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
}
// 设置当前用户
if (loginUser != null) {
SecurityUtils.setLoginUser(loginUser, request);
SecurityFrameworkUtils.setLoginUser(loginUser, request);
}
} catch (Throwable ex) {
CommonResult<?> result = globalExceptionHandler.allExceptionHandler(request, ex);

View File

@@ -2,7 +2,7 @@ package cn.iocoder.dashboard.framework.security.core.handler;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.dashboard.util.servlet.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
@@ -35,7 +35,7 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
throws IOException, ServletException {
// 打印 warn 的原因是,不定期合并 warn看看有没恶意破坏
log.warn("[commence][访问 URL({}) 时,用户({}) 权限不够]", request.getRequestURI(),
SecurityUtils.getLoginUser().getId(), e);
SecurityFrameworkUtils.getLoginUser().getId(), e);
// 返回 403
ServletUtils.writeJSON(response, CommonResult.error(UNAUTHORIZED));
}

View File

@@ -3,7 +3,7 @@ package cn.iocoder.dashboard.framework.security.core.handler;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.service.SecurityAuthFrameworkService;
import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.dashboard.util.servlet.ServletUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
@@ -31,7 +31,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
// 执行退出
String token = SecurityUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
if (StrUtil.isNotBlank(token)) {
securityFrameworkService.logout(token);
}

View File

@@ -1,6 +1,7 @@
package cn.iocoder.dashboard.framework.security.core.util;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.framework.web.core.util.WebFrameworkUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
@@ -12,11 +13,11 @@ import java.util.Set;
/**
* 安全服务工具类
*
* @author ruoyi
* @author 芋道源码
*/
public class SecurityUtils {
public class SecurityFrameworkUtils {
private SecurityUtils() {}
private SecurityFrameworkUtils() {}
/**
* 从请求中获得认证 Token
@@ -45,7 +46,7 @@ public class SecurityUtils {
}
/**
* 获得当前用户的编号
* 获得当前用户的编号从上下文中
*
* @return 用户编号
*/
@@ -53,6 +54,11 @@ public class SecurityUtils {
return getLoginUser().getId();
}
/**
* 获得当前用户的角色编号数组
*
* @return 角色编号数组
*/
public static Set<Long> getLoginUserRoleIds() {
return getLoginUser().getRoleIds();
}
@@ -70,6 +76,9 @@ public class SecurityUtils {
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// 设置到上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
// 额外设置到 request 用于 ApiAccessLogFilter 可以获取到用户编号
// 原因是Spring Security Filter ApiAccessLogFilter 后面在它记录访问日志时线上上下文已经没有用户编号等信息
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
}
}