{"record":{"id":"6e4ebe671cb1d216","repo":"dromara/Sa-Token","slug":"12303","errorCode":"12303","errorMessage":"API Key 已被禁用: ","messagePattern":"API Key 已被禁用: ","errorType":"exception","errorClass":"ApiKeyException","httpStatus":null,"severity":"error","filePath":"sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/template/SaApiKeyTemplate.java","lineNumber":133,"sourceCode":"\t\t}\n\t\treturn apiKeyModel;\n\t}\n\n\t/**\n\t * 校验 ApiKey，成功返回 ApiKeyModel，失败则抛出异常\n\t * @param apiKey /\n\t * @return /\n\t */\n\tpublic ApiKeyModel checkApiKey(String apiKey) {\n\t\tApiKeyModel ak = getApiKey(apiKey);\n\t\tif(ak == null) {\n\t\t\tthrow new ApiKeyException(\"无效 API Key: \" + apiKey).setApiKey(apiKey).setCode(SaApiKeyErrorCode.CODE_12301);\n\t\t}\n\t\tif(ak.timeExpired()) {\n\t\t\tthrow new ApiKeyException(\"API Key 已过期: \" + apiKey).setApiKey(apiKey).setCode(SaApiKeyErrorCode.CODE_12302);\n\t\t}\n\t\tif(! ak.getIsValid()) {\n\t\t\tthrow new ApiKeyException(\"API Key 已被禁用: \" + apiKey).setApiKey(apiKey).setCode(SaApiKeyErrorCode.CODE_12303);\n\t\t}\n\t\treturn ak;\n\t}\n\n\t/**\n\t * 持久化：ApiKeyModel\n\t * @param ak /\n\t */\n\tpublic void saveApiKey(ApiKeyModel ak) {\n\t\tif(ak == null) {\n\t\t\treturn;\n\t\t}\n\t\t// 数据自检\n\t\tak.checkByCanSaved();\n\n\t\t// 保存 ApiKeyModel\n\t\tString saveKey = splicingApiKeySaveKey(ak.getApiKey());\n\t\tif(ak.timeExpired()) {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-plugin/sa-token-apikey/src/main/java/cn/dev33/satoken/apikey/template/SaApiKeyTemplate.java#L115-L151","documentation":"Thrown by SaApiKeyTemplate.checkApiKey(String) when the key record exists and is not expired but ak.getIsValid() is false — the key was administratively disabled. Code 12303 marks a disabled key, distinct from unknown (12301) and expired (12302).","triggerScenarios":"Calling checkApiKey (directly or through checkApiKeyScope / checkApiKeyScopeOr) on a key whose isValid flag was set to false, e.g. after updateApiKey or a disable operation.","commonSituations":"Security incident response disabling a leaked key; toggling isValid=false during testing and forgetting to re-enable; a disabled key still configured in a downstream client.","solutions":["Re-enable the key: load the model, setIsValid(true), and save it back (or use the template's update API)","If the disable was intentional, remove the key from the client's configuration and issue a replacement","Audit who/what disabled the key before re-enabling it"],"exampleFix":"// before\nsaApiKeyTemplate.checkApiKey(disabledKey); // isValid=false -> throws 12303\n\n// after\nApiKeyModel ak = saApiKeyTemplate.getApiKey(disabledKey);\nak.setIsValid(true);\nsaApiKeyTemplate.updateApiKey(ak);\nsaApiKeyTemplate.checkApiKey(disabledKey);","handlingStrategy":"try-catch","validationCode":"ApiKeyModel ak = saApiKeyTemplate.getApiKey(apiKey);\nif (ak != null && !Boolean.TRUE.equals(ak.getIsValid())) {\n    return unavailable(\"api key disabled\");\n}","typeGuard":null,"tryCatchPattern":"catch (ApiKeyException e) { if (e.getCode() == SaApiKeyErrorCode.CODE_12303) { /* 403: key disabled, alert ops */ } else throw e; }","preventionTips":["Treat 12303 as a security signal — disabled keys should not be silently re-enabled","Keep an audit log of enable/disable operations on keys"],"tags":["sa-token","apikey","auth","disabled"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}