登录鉴权按照Source判断id来自于何处

This commit is contained in:
litianxiang
2026-05-13 09:40:30 +08:00
parent 4d3b22de82
commit 83cbd57dea
6 changed files with 160 additions and 116 deletions

View File

@@ -263,6 +263,12 @@
<version>2.15.1</version> <version>2.15.1</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
</dependency>
<dependency> <dependency>
<groupId>com.stripe</groupId> <groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId> <artifactId>stripe-java</artifactId>

View File

@@ -1,89 +1,99 @@
package com.ai.da.common.config.exception; package com.ai.da.common.config.exception;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.ai.da.common.response.ResultEnum; import com.ai.da.common.response.ResultEnum;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/** import org.springframework.web.bind.annotation.ResponseStatus;
* @author: dangweijian
* @description: 全局异常捕获 /**
* @create: 2019-12-03 10:24 * @author: dangweijian
**/ * @description: 全局异常捕获
@Slf4j * @create: 2019-12-03 10:24
@ControllerAdvice **/
public class ExceptionCatch { @Slf4j
@ControllerAdvice
/** public class ExceptionCatch {
* 线程安全,且构建后不可更改
*/ /**
private static ImmutableMap<Class<? extends Throwable>, ResultEnum> EXCEPTIONS; * 线程安全,且构建后不可更改
*/
/** private static ImmutableMap<Class<? extends Throwable>, ResultEnum> EXCEPTIONS;
* 用于构建ImmutableMap
*/ /**
private static ImmutableMap.Builder<Class<? extends Throwable>, ResultEnum> builder = ImmutableMap.builder(); * 用于构建ImmutableMap
*/
@ResponseBody private static ImmutableMap.Builder<Class<? extends Throwable>, ResultEnum> builder = ImmutableMap.builder();
@ExceptionHandler(BusinessException.class)
public Response<String> businessExceptionCatch(BusinessException e) { @ResponseBody
log.error("发生业务异常,code:[{}],msg:[{}]", e.getCode(), e.getMsg(), e); @ExceptionHandler(BusinessException.class)
return Response.error(e.getCode(), e.getMsg()); public Response<String> businessExceptionCatch(BusinessException e) {
} log.error("发生业务异常,code:[{}],msg:[{}]", e.getCode(), e.getMsg(), e);
return Response.error(e.getCode(), e.getMsg());
@ResponseBody }
@ExceptionHandler(Exception.class)
public Response<String> exceptionCatch(Exception e) { @ResponseBody
log.error("发生系统异常,message:[{}]", e.getMessage(), e); @ResponseStatus(HttpStatus.UNAUTHORIZED)
//如果ImmutableMap集合为空,构建ImmutableMap @ExceptionHandler(UnauthorizedException.class)
if (EXCEPTIONS == null || EXCEPTIONS.size() == 0) { public Response<String> unauthorizedExceptionCatch(UnauthorizedException e) {
EXCEPTIONS = builder.build(); log.error("Unauthorized: {}", e.getMessage());
} return Response.error(401, e.getMessage());
//获取不可预知异常自定义错误码 }
if (EXCEPTIONS != null) {
ResultEnum resultEnum = EXCEPTIONS.get(e.getClass()); @ResponseBody
if (resultEnum != null) { @ExceptionHandler(Exception.class)
return Response.error(resultEnum.getCode(), resultEnum.getMsg()); public Response<String> exceptionCatch(Exception e) {
} log.error("发生系统异常,message:[{}]", e.getMessage(), e);
} //如果ImmutableMap集合为空,构建ImmutableMap
return Response.error(ResultEnum.ERROR.getCode(), e.getMessage() == null ? ResultEnum.ERROR.getMsg() : e.getMessage()); if (EXCEPTIONS == null || EXCEPTIONS.size() == 0) {
} EXCEPTIONS = builder.build();
}
/** //获取不可预知异常自定义错误码
* 处理参数校验异常 if (EXCEPTIONS != null) {
* ResultEnum resultEnum = EXCEPTIONS.get(e.getClass());
* @param e if (resultEnum != null) {
* @return ResponseData return Response.error(resultEnum.getCode(), resultEnum.getMsg());
*/ }
@ResponseBody }
@ExceptionHandler(BindException.class) return Response.error(ResultEnum.ERROR.getCode(), e.getMessage() == null ? ResultEnum.ERROR.getMsg() : e.getMessage());
public Response<String> bindExceptionHandler(BindException e) { }
log.error("参数错误bind{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage()); /**
return Response.error(businessException.getCode(), businessException.getMsg()); * 处理参数校验异常
} *
* @param e
/** * @return ResponseData
* 处理参数校验异常 */
* @ResponseBody
* @param e @ExceptionHandler(BindException.class)
* @return ResponseData public Response<String> bindExceptionHandler(BindException e) {
*/ log.error("参数错误bind{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
@ResponseBody BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
@ExceptionHandler(MethodArgumentNotValidException.class) return Response.error(businessException.getCode(), businessException.getMsg());
public Response<String> handleValidationException(MethodArgumentNotValidException e) { }
log.error("参数错误bind{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage()); /**
return Response.error(businessException.getCode(), businessException.getMsg()); * 处理参数校验异常
} *
* @param e
//初始化,不可预知异常自定义错误编码 * @return ResponseData
static { */
// builder.put(FileNotFoundException.class, ResultEnum.FILE_NOT_EXIST); @ResponseBody
} @ExceptionHandler(MethodArgumentNotValidException.class)
} public Response<String> handleValidationException(MethodArgumentNotValidException e) {
log.error("参数错误bind{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
BusinessException businessException = new BusinessException(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return Response.error(businessException.getCode(), businessException.getMsg());
}
//初始化,不可预知异常自定义错误编码
static {
// builder.put(FileNotFoundException.class, ResultEnum.FILE_NOT_EXIST);
}
}

View File

@@ -0,0 +1,12 @@
package com.ai.da.common.config.exception;
public class UnauthorizedException extends RuntimeException {
public UnauthorizedException(String message) {
super(message);
}
public UnauthorizedException() {
super("Gateway token verification failed");
}
}

View File

@@ -1,19 +1,41 @@
package com.ai.da.common.context; package com.ai.da.common.context;
import com.ai.da.model.vo.AuthPrincipalVo; import com.ai.da.model.vo.AuthPrincipalVo;
public class UserContext { public class UserContext {
private static ThreadLocal<AuthPrincipalVo> userHolder = new ThreadLocal<AuthPrincipalVo>(); private static final ThreadLocal<AuthPrincipalVo> userHolder = new ThreadLocal<>();
public static AuthPrincipalVo getUserHolder() { public static void setUserHolder(AuthPrincipalVo authPrincipalVo) {
return userHolder.get(); userHolder.set(authPrincipalVo);
} }
public static void delete() { public static AuthPrincipalVo getUserHolder() {
userHolder.remove(); AuthPrincipalVo holder = userHolder.get();
} if (holder == null) {
throw new RuntimeException("User not authenticated");
public static void setUserHolder(AuthPrincipalVo authPrincipalVo) { }
userHolder.set(authPrincipalVo); if (!"AIDA".equals(holder.getSource())) {
} throw new RuntimeException("Access denied: source must be AIDA");
} }
return holder;
}
public static void delete() {
userHolder.remove();
}
public static Long getUserId() {
return getUserHolder().getId();
}
public static Long getBuyerId() {
AuthPrincipalVo holder = userHolder.get();
if (holder == null) {
throw new RuntimeException("User not authenticated");
}
if (!"BUYER".equals(holder.getSource())) {
throw new RuntimeException("Access denied: source must be BUYER");
}
return holder.getId();
}
}

View File

@@ -358,6 +358,8 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
principal.setUsername(account.getUserName()); principal.setUsername(account.getUserName());
principal.setLanguage(account.getLanguage()); principal.setLanguage(account.getLanguage());
principal.setCountry(account.getCountry()); principal.setCountry(account.getCountry());
//区分买家端登录
principal.setSource("AIDA");
String token2 = tokenGenerateUtils.createToken(principal); String token2 = tokenGenerateUtils.createToken(principal);
// 本地 JVM 缓存(适配旧逻辑) // 本地 JVM 缓存(适配旧逻辑)
LocalCacheUtils.setTokenCache(String.valueOf(account.getId()), token2); LocalCacheUtils.setTokenCache(String.valueOf(account.getId()), token2);

View File

@@ -11,14 +11,6 @@ spring:
application: application:
name: aida-back name: aida-back
# ---------- 副数据源back 私有,由 Nacos 统一管理) ----------
# ---------- Token 生成参数(由 TokenGenerateUtils 使用) ----------
security:
jwtSecret: JWTSECRET
jwtTokenHeader: Authorization
jwtTokenPrefix: Bearer-
jwtExpiration: 8640000000
# ---------- MinIO Buckets ---------- # ---------- MinIO Buckets ----------
minio: minio: