|
|
@@ -14,7 +14,9 @@ import com.zsElectric.boot.common.constant.SecurityConstants;
|
|
|
import com.zsElectric.boot.core.exception.BusinessException;
|
|
|
import com.zsElectric.boot.core.web.ResultCode;
|
|
|
import com.zsElectric.boot.config.property.SecurityProperties;
|
|
|
+import com.zsElectric.boot.security.model.AppletUserDetails;
|
|
|
import com.zsElectric.boot.security.model.AuthenticationToken;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import com.zsElectric.boot.security.model.SysUserDetails;
|
|
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
|
@@ -40,6 +42,7 @@ import java.util.stream.Collectors;
|
|
|
* @author Ray.Hao
|
|
|
* @since 2024/11/15
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@ConditionalOnProperty(value = "security.session.type", havingValue = "jwt")
|
|
|
@Service
|
|
|
public class JwtTokenManager implements TokenManager {
|
|
|
@@ -136,26 +139,39 @@ public class JwtTokenManager implements TokenManager {
|
|
|
JWT jwt = JWTUtil.parseToken(token);
|
|
|
// 检查 Token 是否有效(验签 + 是否过期)
|
|
|
boolean isValid = jwt.setKey(secretKey).validate(0);
|
|
|
+
|
|
|
+ log.debug("[JWT验证] Token基础验证结果: {}", isValid);
|
|
|
|
|
|
if (isValid) {
|
|
|
// 检查 Token 是否已被加入黑名单(注销、修改密码等场景)
|
|
|
JSONObject payloads = jwt.getPayloads();
|
|
|
String jti = payloads.getStr(JWTPayload.JWT_ID);
|
|
|
+ String username = payloads.getStr(JWTPayload.SUBJECT);
|
|
|
+ Date expiresAt = payloads.getDate(JWTPayload.EXPIRES_AT);
|
|
|
+
|
|
|
+ log.debug("[JWT验证] 用户: {}, jti: {}, 过期时间: {}", username, jti, expiresAt);
|
|
|
+
|
|
|
if(validateRefreshToken) {
|
|
|
//刷新token需要校验token类别
|
|
|
boolean isRefreshToken = payloads.getBool(JwtClaimConstants.TOKEN_TYPE);
|
|
|
if (!isRefreshToken) {
|
|
|
+ log.warn("[JWT验证失败] Token类型不是刷新令牌");
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
// 判断是否在黑名单中,如果在,则返回 false 标识Token无效
|
|
|
- if (Boolean.TRUE.equals(redisTemplate.hasKey(StrUtil.format(RedisConstants.Auth.BLACKLIST_TOKEN, jti)))) {
|
|
|
+ String blacklistKey = StrUtil.format(RedisConstants.Auth.BLACKLIST_TOKEN, jti);
|
|
|
+ if (Boolean.TRUE.equals(redisTemplate.hasKey(blacklistKey))) {
|
|
|
+ log.warn("[JWT验证失败] Token已在黑名单中, jti: {}", jti);
|
|
|
return false;
|
|
|
}
|
|
|
+ log.debug("[JWT验证成功] 用户: {}", username);
|
|
|
+ } else {
|
|
|
+ log.warn("[JWT验证失败] Token验签失败或已过期");
|
|
|
}
|
|
|
return isValid;
|
|
|
- } catch (Exception gitignore) {
|
|
|
- // token 验证
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error("[JWT验证异常] 异常信息: {}", ex.getMessage());
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
@@ -240,11 +256,29 @@ public class JwtTokenManager implements TokenManager {
|
|
|
* @return JWT Token
|
|
|
*/
|
|
|
private String generateToken(Authentication authentication, int ttl, boolean isRefreshToken) {
|
|
|
- SysUserDetails userDetails = (SysUserDetails) authentication.getPrincipal();
|
|
|
+ Object principal = authentication.getPrincipal();
|
|
|
Map<String, Object> payload = new HashMap<>();
|
|
|
- payload.put(JwtClaimConstants.USER_ID, userDetails.getUserId()); // 用户ID
|
|
|
- payload.put(JwtClaimConstants.DEPT_ID, userDetails.getDeptId()); // 部门ID
|
|
|
- payload.put(JwtClaimConstants.DATA_SCOPE, userDetails.getDataScope()); // 数据权限范围
|
|
|
+
|
|
|
+ // 根据不同的用户类型设置payload
|
|
|
+ if (principal instanceof AppletUserDetails) {
|
|
|
+ // 小程序用户
|
|
|
+ AppletUserDetails appletUser = (AppletUserDetails) principal;
|
|
|
+ payload.put(JwtClaimConstants.USER_ID, appletUser.getUserId()); // 用户ID (c_user_info表)
|
|
|
+ payload.put(JwtClaimConstants.DEPT_ID, null); // 小程序用户无部门
|
|
|
+ payload.put(JwtClaimConstants.DATA_SCOPE, null); // 小程序用户无数据权限范围
|
|
|
+
|
|
|
+ log.debug("生成小程序用户Token, userId: {}, phone: {}", appletUser.getUserId(), appletUser.getPhone());
|
|
|
+ } else if (principal instanceof SysUserDetails) {
|
|
|
+ // 系统用户
|
|
|
+ SysUserDetails sysUser = (SysUserDetails) principal;
|
|
|
+ payload.put(JwtClaimConstants.USER_ID, sysUser.getUserId()); // 用户ID (sys_user表)
|
|
|
+ payload.put(JwtClaimConstants.DEPT_ID, sysUser.getDeptId()); // 部门ID
|
|
|
+ payload.put(JwtClaimConstants.DATA_SCOPE, sysUser.getDataScope()); // 数据权限范围
|
|
|
+
|
|
|
+ log.debug("生成系统用户Token, userId: {}, username: {}", sysUser.getUserId(), sysUser.getUsername());
|
|
|
+ } else {
|
|
|
+ throw new BusinessException("不支持的用户类型: " + principal.getClass().getName());
|
|
|
+ }
|
|
|
|
|
|
// claims 中添加角色信息
|
|
|
Set<String> roles = authentication.getAuthorities().stream()
|