{"record":{"id":"546ecc760892071e","repo":"Tencent/APIJSON","slug":"error-546ecc","errorCode":null,"errorMessage":"{} 不允许 {} 用户的 {} 请求！","messagePattern":"(.+?) 不允许 (.+?) 用户的 (.+?) 请求！","errorType":"exception","errorClass":"IllegalAccessException","httpStatus":403,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":322,"sourceCode":"\t * @throws Exception\n\t * @see {@link JSONMap#KEY_ROLE}\n\t */\n\tpublic void verifyAllowRole(SQLConfig<T, M, L> config, String table, RequestMethod method, String role) throws Exception {\n\t\tLog.d(TAG, \"verifyAllowRole  table = \" + table + \"; method = \" + method + \"; role = \" + role);\n\t\tif (table == null) {\n\t\t\ttable = config == null ? null : config.getTable();\n\t\t}\n\n\t\tif (table != null) {\n\t\t\tif (method == null) {\n\t\t\t\tmethod = config == null ? GET : config.getMethod();\n\t\t\t}\n\t\t\tif (role == null) {\n\t\t\t\trole = config == null ? UNKNOWN : config.getRole();\n\t\t\t}\n\n\t\t\tif (Log.DEBUG == false && SYSTEM_ACCESS_MAP.get(table) != null) {\n\t\t\t\tthrow new IllegalAccessException(table + \" 不允许 \" + role + \" 用户的 \" + method.name() + \" 请求！\");\n\t\t\t}\n\n\t\t\tMap<RequestMethod, String[]> map = ACCESS_MAP.get(table);\n\n\t\t\tif (map == null || Arrays.asList(map.get(method)).contains(role) == false) {\n\t\t\t\tthrow new IllegalAccessException(table + \" 不允许 \" + role + \" 用户的 \" + method.name() + \" 请求！\");\n\t\t\t}\n\t\t}\n\t}\n\n\t/**校验请求使用的角色，角色不好判断，让访问者发过来角色名，OWNER,CONTACT,ADMIN等\n\t * @param config\n\t * @param table\n\t * @param method\n\t * @param role\n\t * @return\n\t * @throws Exception\n\t * @see {@link JSONMap#KEY_ROLE}","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L304-L340","documentation":"In verifyRole(), when the target table is registered in SYSTEM_ACCESS_MAP and Log.DEBUG is false, any request from a non-privileged path is refused with IllegalAccessException. SYSTEM_ACCESS_MAP lists tables reserved for the framework itself (such as access/system configuration tables); in production mode (DEBUG off) they are unreachable through the normal API. This is a deliberate hard block, not a role-mapping problem.","triggerScenarios":"A client sends a GET/POST/PUT/DELETE against a table that exists in SYSTEM_ACCESS_MAP (framework system table) while Log.DEBUG == false; the first branch in verifyRole throws regardless of the role sent.","commonSituations":"Running the same requests that worked in local DEBUG mode against a production deployment where Log.DEBUG=false; probing framework tables (e.g. '_access' style config tables) through the public API; forgetting that system tables are only accessible in debug builds.","solutions":["Stop querying the system/reserved table from client requests — expose the data through a dedicated controller or a copy of the data in a normal table.","If this is an administration tool run in a trusted debug deployment, set Log.DEBUG = true (development only; never in production).","Re-check that the table name in the request is actually the business table you meant — a typo can resolve to a system table name pattern."],"exampleFix":"// before (production, Log.DEBUG == false)\n{ \"Request\": { } }  // Request is a system table -> blocked\n\n// after\n// Query a normal business table, or read system data via a custom controller\n{ \"MyAppConfig\": { \"id\": 1 } }","handlingStrategy":"validation","validationCode":"// client/server pre-check: never route system tables through the public API\nif (Log.DEBUG == false && SYSTEM_ACCESS_MAP.containsKey(tableName)) {\n    reject(\"table \" + tableName + \" is a system table and not accessible in production\");\n}","typeGuard":"boolean isSystemTable(String t) { return AbstractVerifier.SYSTEM_ACCESS_MAP.containsKey(t); }","tryCatchPattern":"catch (IllegalAccessException e) { respond 403; log the blocked table+role+method for audit; never retry with different roles to probe.","preventionTips":["Keep an explicit allowlist of client-queryable tables; reject system tables at the controller edge.","Run the same DEBUG=false profile in staging as in production so system-table requests fail there first."],"tags":["apijson","permissions","system-tables","production"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}