{"record":{"id":"2c29e5e150496fda","repo":"paascloud/paascloud-master","slug":"uac10011039","errorCode":"UAC10011039","errorMessage":"UAC10011039","messagePattern":"UAC10011039","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"paascloud-common/paascloud-common-core/src/main/java/com/paascloud/core/utils/RequestUtil.java","lineNumber":112,"sourceCode":"\t\t}\n\t\t// 对于通过多个代理的情况, 第一个IP为客户端真实IP,多个IP按照','分割 //\"***.***.***.***\".length() = 15\n\t\tif (ipAddress != null && ipAddress.length() > GlobalConstant.MAX_IP_LENGTH) {\n\t\t\tif (ipAddress.indexOf(GlobalConstant.Symbol.COMMA) > 0) {\n\t\t\t\tipAddress = ipAddress.substring(0, ipAddress.indexOf(GlobalConstant.Symbol.COMMA));\n\t\t\t}\n\t\t}\n\t\treturn ipAddress;\n\t}\n\n\t/**\n\t * Gets login user.\n\t *\n\t * @return the login user\n\t */\n\tpublic static LoginAuthDto getLoginUser() {\n\t\tLoginAuthDto loginAuthDto = (LoginAuthDto) ThreadLocalMap.get(GlobalConstant.Sys.TOKEN_AUTH_DTO);\n\t\tif (PublicUtil.isEmpty(loginAuthDto)) {\n\t\t\tthrow new BusinessException(ErrorCodeEnum.UAC10011039);\n\t\t}\n\t\treturn loginAuthDto;\n\n\t}\n\n\t/**\n\t * Gets auth header.\n\t *\n\t * @param request the request\n\t *\n\t * @return the auth header\n\t */\n\tpublic static String getAuthHeader(HttpServletRequest request) {\n\n\t\tString authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);\n\t\tif (org.apache.commons.lang.StringUtils.isEmpty(authHeader)) {\n\t\t\tthrow new BusinessException(ErrorCodeEnum.UAC10011040);\n\t\t}","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-common/paascloud-common-core/src/main/java/com/paascloud/core/utils/RequestUtil.java#L94-L130","documentation":"RequestUtil.getLoginUser throws ErrorCodeEnum.UAC10011039 when no LoginAuthDto is present in the ThreadLocal under TOKEN_AUTH_DTO. Like BaseController.getLoginAuthDto, it signals that the current thread has no authenticated user — the request was unauthenticated or the auth layer never populated the ThreadLocal.","triggerScenarios":"Calling RequestUtil.getLoginUser() from code executing without a populated ThreadLocalMap entry: no token, invalid/expired token, or calls from async threads (where ThreadLocal does not propagate).","commonSituations":"Internal service calls bypassing the gateway, @Async or thread-pool tasks losing the request context, expired JWTs, or endpoints excluded from the auth interceptor by mistake.","solutions":["Ensure a valid Authorization token is present so the auth filter populates ThreadLocalMap before this call.","For async work, capture LoginAuthDto in the request thread and pass it explicitly (or use a context-propagating decorator).","Check interceptor path patterns so this endpoint is actually covered by authentication."],"exampleFix":"// before (in @Async method)\nLoginAuthDto user = RequestUtil.getLoginUser();\n// after\nLoginAuthDto user = RequestUtil.getLoginUser(); // capture in caller\nasyncService.doWork(user); // pass explicitly","handlingStrategy":"validation","validationCode":"Object ctx = ThreadLocalMap.get(GlobalConstant.Sys.TOKEN_AUTH_DTO);\nif (!(ctx instanceof LoginAuthDto)) {\n    throw new AuthenticationException(\"no login user bound to current thread\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    LoginAuthDto user = RequestUtil.getLoginUser();\n} catch (BusinessException e) {\n    return ResponseEntity.status(401).build();\n}","preventionTips":["Capture LoginAuthDto in the request thread before dispatching async work.","Use a TaskDecorator to propagate request context to worker threads.","Confirm endpoints relying on getLoginUser are covered by the auth interceptor."],"tags":["authentication","threadlocal","missing-user","async"],"backgroundTag":"authentication-required","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}