{"record":{"id":"d6d055f92229bf66","repo":"jeecgboot/JeecgBoot","slug":"system-permission-limit","errorCode":"system_permission_limit","errorMessage":"system_permission_limit[username=${userName}]","messagePattern":"system_permission_limit\\[username=(.+?)\\]","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/framework/util/JobGroupPermissionUtil.java","lineNumber":40,"sourceCode":"     * check if has jobgroup permission\n     */\n    public static boolean hasJobGroupPermission(LoginInfo loginInfo, int jobGroup){\n        if (XxlSsoHelper.hasRole(loginInfo, Consts.ADMIN_ROLE).isSuccess()) {\n            return true;\n        } else {\n            List<String> jobGroups = (loginInfo.getExtraInfo()!=null && loginInfo.getExtraInfo().containsKey(\"jobGroups\"))\n                    ? StringTool.split(loginInfo.getExtraInfo().get(\"jobGroups\"), \",\") :new ArrayList<>();\n            return jobGroups.contains(String.valueOf(jobGroup));\n        }\n    }\n\n    /**\n     * valid jobGroup permission\n     */\n    public static LoginInfo validJobGroupPermission(HttpServletRequest request, int jobGroup) {\n        Response<LoginInfo> loginInfoResponse = XxlSsoHelper.loginCheckWithAttr(request);\n        if (!(loginInfoResponse.isSuccess() && hasJobGroupPermission(loginInfoResponse.getData(), jobGroup))) {\n            throw new RuntimeException(I18nUtil.getString(\"system_permission_limit\") + \"[username=\"+ loginInfoResponse.getData().getUserName() +\"]\");\n        }\n        return loginInfoResponse.getData();\n    }\n\n    /**\n     * filter jobGroupList by permission\n     */\n    public static List<XxlJobGroup> filterJobGroupByPermission(HttpServletRequest request, List<XxlJobGroup> jobGroupListTotal){\n        Response<LoginInfo>  loginInfoResponse = XxlSsoHelper.loginCheckWithAttr(request);\n\n        if (XxlSsoHelper.hasRole(loginInfoResponse.getData(), Consts.ADMIN_ROLE).isSuccess()) {\n            return jobGroupListTotal;\n        } else {\n            List<String> jobGroups = (loginInfoResponse.getData().getExtraInfo()!=null\n                    && loginInfoResponse.getData().getExtraInfo().get(\"jobGroups\")!=null\n            )\n                    ? StringTool.split(loginInfoResponse.getData().getExtraInfo().get(\"jobGroups\"), \",\")\n                    :new ArrayList<>();","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/framework/util/JobGroupPermissionUtil.java#L22-L58","documentation":"Thrown as a RuntimeException from JobGroupPermissionUtil.validJobGroupPermission when the SSO login check succeeds but the authenticated user does not have permission for the requested jobGroup. The error message uses the i18n key 'system_permission_limit' (typically resolving to a localized 'insufficient permissions' string) appended with the username. This is an authorization enforcement point — the user is authenticated but lacks the specific job-group-level access.","triggerScenarios":"An authenticated user attempts to access or operate on an XXL-Job scheduler job group (jobGroup ID) that is not in their allowed list. The permission list comes from loginInfo.getExtraInfo().get(\"jobGroups\") — a comma-separated list of allowed job group IDs attached to the SSO session. If the requested jobGroup ID is not in that list, the exception fires.","commonSituations":"New user not assigned to the correct job group in SSO/identity management; job group ID changed but user permissions were not updated; admin created a new job group but did not assign it to operators; cross-tenant access attempt; misconfigured SSO extra info attribute name ('jobGroups').","solutions":["Assign the missing jobGroup ID to the user's 'jobGroups' attribute in the SSO/identity system and have them re-authenticate.","Verify the SSO login info correctly populates the 'jobGroups' extra info attribute — check attribute mapping configuration.","If the user should be an admin with full access, grant them the ADMIN_ROLE so hasJobGroupPermission returns true unconditionally.","Confirm the jobGroup ID in the request matches the IDs configured in the permission system."],"exampleFix":"// before — user has jobGroups=\"1,2\" but requests jobGroup=3\nvalidJobGroupPermission(request, 3);  // throws\n// after — admin grants jobGroup 3 to user in SSO, or:\n// grant ADMIN_ROLE to user so filterJobGroupByPermission returns all groups","handlingStrategy":"try-catch","validationCode":"// Check permission before calling the protected API\nResponse<LoginInfo> resp = XxlSsoHelper.loginCheckWithAttr(request);\nif (resp.isSuccess() && JobGroupPermissionUtil.hasJobGroupPermission(resp.getData(), jobGroup)) {\n    // proceed with the operation\n} else {\n    return Response.fail(\"Insufficient permission for job group: \" + jobGroup);\n}","typeGuard":"boolean canAccessJobGroup(HttpServletRequest request, int jobGroup) {\n    Response<LoginInfo> resp = XxlSsoHelper.loginCheckWithAttr(request);\n    return resp.isSuccess() && JobGroupPermissionUtil.hasJobGroupPermission(resp.getData(), jobGroup);\n}","tryCatchPattern":"try {\n    LoginInfo info = JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);\n    // proceed\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"system_permission_limit\")) {\n        // return 403 with user-friendly message\n        return Response.fail(403, \"You do not have access to this job group\");\n    }\n    throw e;\n}","preventionTips":["Assign the correct jobGroup IDs to users in the SSO/identity system.","Verify the 'jobGroups' extra info attribute is populated on login.","Grant ADMIN_ROLE to users who need unrestricted job group access.","Filter the job group dropdown by the user's permitted groups in the UI."],"tags":["permission","authorization","sso","xxljob","security","runtime"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}