Files
aca-classroom-service/src/main/java/com/yunhai/acaclassroom/aspect/ControllerUserContextAspect.java
T
wanghu 0e75efa023
build / build-push (push) Failing after 2m7s
commit
2026-10-20 09:13:14 +08:00

105 lines
4.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.yunhai.acaclassroom.aspect;
import com.yunhai.acaclassroom.utils.UserContext;
import com.yunhai.platform.auth.BoaUserContext;
import com.yunhai.platform.utils.model.BoaUser;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* 把基础平台的当前登录用户({@link BoaUser})复制到自有 {@link UserContext}(ThreadLocal),请求结束清理。
* <p>参照 UserclassService 的 ControllerUserContextAspect:优先从控制器入参里的 {@code BoaUser} 取,
* 否则回退到框架 {@code BoaUserContext#get()}。本模块为纯教师端,无视角切换。</p>
*/
@Aspect
@Component
@Order(1)
public class ControllerUserContextAspect {
private static final Logger log = LoggerFactory.getLogger(ControllerUserContextAspect.class);
/** 本地联调开关(默认关闭):无 SSO 会话时用固定开发身份填充 UserContext,便于无登录端到端联调。生产严禁开启。 */
@Value("${acaclassroom.dev-context.enabled:false}")
private boolean devContextEnabled;
@Around("execution(* com.yunhai.acaclassroom.controller..*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
try {
BoaUser boaUser = resolveBoaUser(pjp.getArgs());
UserContext.UserInfo info = new UserContext.UserInfo();
if (boaUser != null) {
info.userId = boaUser.getId();
info.userName = boaUser.getName();
info.type = boaUser.getType();
if (boaUser.getCurrentRole() != null) {
info.schId = boaUser.getCurrentRole().getSchId();
} else if (boaUser.getSchool() != null) {
info.schId = boaUser.getSchool().getId();
}
if (boaUser.getRoleIds() != null && !boaUser.getRoleIds().isEmpty()) {
info.roleId = boaUser.getRoleIds().get(0);
}
} else if (devContextEnabled) {
info.userId = 99999;
info.userName = "本地开发";
info.schId = 1;
log.debug("[UserContext] 无 SSO 会话,已使用本地开发身份(schId=1)");
}
info.ip = clientIp();
UserContext.set(info);
return pjp.proceed();
} finally {
UserContext.clear();
}
}
/** 控制器入参中若声明了 BoaUser(框架有参数解析器注入),优先用它;否则取 ThreadLocal 门面。 */
private BoaUser resolveBoaUser(Object[] args) {
if (args != null) {
for (Object a : args) {
if (a instanceof BoaUser) {
return (BoaUser) a;
}
}
}
try {
return BoaUserContext.get();
} catch (Exception e) {
log.debug("[UserContext] 读取 BoaUserContext 失败: {}", e.getMessage());
return null;
}
}
private HttpServletRequest request() {
Object attrs = RequestContextHolder.getRequestAttributes();
return attrs instanceof ServletRequestAttributes ? ((ServletRequestAttributes) attrs).getRequest() : null;
}
private String clientIp() {
HttpServletRequest req = request();
if (req == null) {
return null;
}
String ip = req.getHeader("X-Forwarded-For");
if (ip != null && !ip.isEmpty()) {
int comma = ip.indexOf(',');
return comma > 0 ? ip.substring(0, comma).trim() : ip.trim();
}
ip = req.getHeader("X-Real-IP");
if (ip != null && !ip.isEmpty()) {
return ip.trim();
}
return req.getRemoteAddr();
}
}