{"record":{"id":"2cd54588001e2add","repo":"iflytek/astron-agent","slug":"unauthorized-2cd545","errorCode":"UNAUTHORIZED","errorMessage":"UNAUTHORIZED","messagePattern":"UNAUTHORIZED","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowArtifactService.java","lineNumber":390,"sourceCode":"        if (artifact == null) {\n            throw new BusinessException(ResponseEnum.DATA_NOT_EXIST);\n        }\n        return artifact;\n    }\n\n    private LambdaQueryWrapper<WorkflowArtifact> scopeQuery(Long workflowId) {\n        LambdaQueryWrapper<WorkflowArtifact> wrapper = Wrappers.lambdaQuery(WorkflowArtifact.class)\n                .eq(WorkflowArtifact::getWorkflowId, workflowId)\n                .eq(WorkflowArtifact::getDeleted, Boolean.FALSE);\n        applyCurrentArtifactScope(wrapper);\n        return wrapper;\n    }\n\n    private void applyCurrentArtifactScope(LambdaQueryWrapper<WorkflowArtifact> wrapper) {\n        String currentUid = UserInfoManagerHandler.getUserId();\n        Long spaceId = SpaceInfoUtil.getSpaceId();\n        if (StringUtils.isBlank(currentUid)) {\n            throw new BusinessException(ResponseEnum.UNAUTHORIZED);\n        }\n        if (spaceId != null) {\n            if (spaceUserService.getRole(spaceId, currentUid) == null) {\n                throw new BusinessException(ResponseEnum.INSUFFICIENT_PERMISSIONS);\n            }\n            wrapper.eq(WorkflowArtifact::getSpaceId, spaceId);\n        } else {\n            wrapper.isNull(WorkflowArtifact::getSpaceId)\n                    .eq(WorkflowArtifact::getUid, currentUid);\n        }\n    }\n\n    private void assertWorkflowVisible(Long workflowId) {\n        Workflow workflow = workflowMapper.selectOne(Wrappers.lambdaQuery(Workflow.class)\n                .eq(Workflow::getId, workflowId)\n                .eq(Workflow::getDeleted, Boolean.FALSE)\n                .last(\"limit 1\"));\n        if (workflow == null) {","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowArtifactService.java#L372-L408","documentation":"applyCurrentArtifactScope throws UNAUTHORIZED when UserInfoManagerHandler.getUserId() returns a blank user ID, meaning no authenticated user context is present for the request. Every artifact query (getScopedArtifact, scopeQuery) runs through this scoping, so any artifact read/list/delete without a valid session/user is rejected before the DB query is even built.","triggerScenarios":"Calling artifact APIs without a valid login session/token; expired JWT stripped by the gateway so the user context is empty; internal/scheduled jobs calling the service outside a request-scoped security context; missing auth header on direct service calls.","commonSituations":"Token expiry during long UI sessions; requests proxied to the backend without the auth header; testing the API with curl and no Authorization header; background threads invoking service methods without propagating the user context.","solutions":["Authenticate first and retry the request with a valid session token/Authorization header","Check gateway/filter configuration so the auth header reaches UserInfoManagerHandler (not stripped by a proxy)","For background jobs, propagate or impersonate a system user context rather than calling the scoped service directly","Refresh the expired token in the frontend and replay the request"],"exampleFix":"// before: unauthenticated call\ncurl http://console/api/workflow/artifact/123\n// after\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     http://console/api/workflow/artifact/123","handlingStrategy":"validation","validationCode":"// Ensure a session/token exists before calling artifact APIs\nString token = sessionStore.currentToken();\nif (token == null || token.isBlank())\n    throw new AuthRequiredException(\"Login required before artifact operations\");","typeGuard":null,"tryCatchPattern":"try {\n    artifactApi.listArtifacts(workflowId);\n} catch (BusinessException e) {\n    if (\"UNAUTHORIZED\".equals(e.getCode())) {\n        await reauthenticate(); // refresh token then replay\n        return artifactApi.listArtifacts(workflowId);\n    }\n    throw e;\n}","preventionTips":["Attach the Authorization header on every request, including proxied/internal calls","Refresh tokens proactively before long-running sessions expire","For background jobs, propagate the user context or use a designated service account"],"tags":["java","authentication","unauthorized","api","workflow-artifact"],"backgroundTag":"authentication-required","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}