{"record":{"id":"068c47249d4747d7","repo":"iflytek/astron-agent","slug":"missing-bearer-credential","errorCode":null,"errorMessage":"missing bearer credential","messagePattern":"missing bearer credential","errorType":"exception","errorClass":"GatewayAuthException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/gateway/impl/GatewayAuthServiceImpl.java","lineNumber":23,"sourceCode":"import com.iflytek.astron.console.hub.service.gateway.TenantGatewayAuthClient;\nimport org.springframework.stereotype.Service;\nimport org.springframework.util.StringUtils;\n\n@Service\npublic class GatewayAuthServiceImpl implements GatewayAuthService {\n\n    private static final String BEARER_PREFIX = \"Bearer \";\n\n    private final TenantGatewayAuthClient tenantClient;\n\n    public GatewayAuthServiceImpl(TenantGatewayAuthClient tenantClient) {\n        this.tenantClient = tenantClient;\n    }\n\n    @Override\n    public String authenticateWorkflow(String authorizationHeader) {\n        if (!StringUtils.hasText(authorizationHeader) || !authorizationHeader.startsWith(BEARER_PREFIX)) {\n            throw new GatewayAuthException(\"missing bearer credential\");\n        }\n\n        String credential = authorizationHeader.substring(BEARER_PREFIX.length()).trim();\n        String[] parts = credential.split(\":\", -1);\n        if (parts.length != 2 || !StringUtils.hasText(parts[0]) || !StringUtils.hasText(parts[1])) {\n            throw new GatewayAuthException(\"malformed bearer credential\");\n        }\n\n        return tenantClient.verify(parts[0], parts[1])\n                .filter(StringUtils::hasText)\n                .orElseThrow(() -> new GatewayAuthException(\"invalid app credential\"));\n    }\n}\n","sourceCodeStart":5,"sourceCodeEnd":37,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/gateway/impl/GatewayAuthServiceImpl.java#L5-L37","documentation":"GatewayAuthServiceImpl.authenticateWorkflow validates the Authorization header of workflow gateway requests. When the header is absent, empty, or does not start with the configured Bearer prefix, the service immediately rejects the request with GatewayAuthException(\"missing bearer credential\"). It is the first gate of app-credential authentication before the tenant client verifies the credential.","triggerScenarios":"Calling a workflow gateway endpoint without an Authorization header, sending an empty header, or using a scheme other than 'Bearer <credential>' (e.g. raw token, 'Basic', lowercase/other scheme names that fail the BEARER_PREFIX check).","commonSituations":"Clients forgetting to attach the auth header after removing an interceptor; reverse proxies stripping Authorization headers; scripts calling the gateway with curl but omitting -H; misconfigured SDK base clients without default headers.","solutions":["Add the header 'Authorization: Bearer appKey:appSecret' (the credential format this service expects) to the request.","Verify the client/http layer is not stripping the Authorization header (proxies, gateway rewrites).","Check for scheme typos — it must be exactly the Bearer prefix the service defines (case-sensitive startsWith)."],"exampleFix":"// before\ncurl -X POST https://gateway/api/workflow/run -d '{...}'\n// after\ncurl -X POST https://gateway/api/workflow/run -H 'Authorization: Bearer myAppKey:myAppSecret' -d '{...}'","handlingStrategy":"validation","validationCode":"if (!authHeader || !authHeader.startsWith('Bearer ')) { throw new Error('attach Authorization: Bearer <appKey>:<appSecret>'); }","typeGuard":"function hasBearer(h) { return typeof h === 'string' && h.startsWith('Bearer '); }","tryCatchPattern":null,"preventionTips":["Set the Authorization header once in a shared HTTP client interceptor.","Never route gateway traffic through proxies that strip Authorization headers.","Log (redacted) header presence in client debug mode."],"tags":["auth","http-header","gateway"],"backgroundTag":"missing-credentials","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}