xuxueli/xxl-job · error · RuntimeException

Permission limit[username={}]

Error message

Permission limit[username={}]

What it means

Thrown by JobGroupPermissionUtil.validJobGroupPermission as a RuntimeException when the SSO login check fails OR the logged-in user lacks permission for the target jobGroup. The message bundles a localized 'permission limit' string with the username. It guards every admin operation that touches a specific job group.

Source

Thrown at xxl-job-admin/src/main/java/com/xxl/job/admin/framework/util/JobGroupPermissionUtil.java:40

     * check if has jobgroup permission
     */
    public static boolean hasJobGroupPermission(LoginInfo loginInfo, int jobGroup){
        if (XxlSsoHelper.hasRole(loginInfo, Consts.ADMIN_ROLE).isSuccess()) {
            return true;
        } else {
            List<String> jobGroups = (loginInfo.getExtraInfo()!=null && loginInfo.getExtraInfo().containsKey("jobGroups"))
                    ? StringTool.split(loginInfo.getExtraInfo().get("jobGroups"), ",") :new ArrayList<>();
            return jobGroups.contains(String.valueOf(jobGroup));
        }
    }

    /**
     * valid jobGroup permission
     */
    public static LoginInfo validJobGroupPermission(HttpServletRequest request, int jobGroup) {
        Response<LoginInfo> loginInfoResponse = XxlSsoHelper.loginCheckWithAttr(request);
        if (!(loginInfoResponse.isSuccess() && hasJobGroupPermission(loginInfoResponse.getData(), jobGroup))) {
            throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username="+ loginInfoResponse.getData().getUserName() +"]");
        }
        return loginInfoResponse.getData();
    }

    /**
     * filter jobGroupList by permission
     */
    public static List<XxlJobGroup> filterJobGroupByPermission(HttpServletRequest request, List<XxlJobGroup> jobGroupListTotal){
        Response<LoginInfo>  loginInfoResponse = XxlSsoHelper.loginCheckWithAttr(request);

        if (XxlSsoHelper.hasRole(loginInfoResponse.getData(), Consts.ADMIN_ROLE).isSuccess()) {
            return jobGroupListTotal;
        } else {
            List<String> jobGroups = (loginInfoResponse.getData().getExtraInfo()!=null
                    && loginInfoResponse.getData().getExtraInfo().get("jobGroups")!=null
            )
                    ? StringTool.split(loginInfoResponse.getData().getExtraInfo().get("jobGroups"), ",")
                    :new ArrayList<>();

View on GitHub (pinned to e74c784f68)

Solutions

  1. Grant the user's identity the missing jobGroup id in the 'jobGroups' attribute (comma-separated).
  2. Re-authenticate / refresh the SSO session if it expired.
  3. Confirm the request targets a jobGroup the user actually owns; admins (ADMIN_ROLE) bypass the filter entirely.
  4. Ensure loginInfoResponse.getData() is non-null before permission checks to avoid an NPE masking the real cause.

Example fix

// before: user has jobGroups "1,2" but request targets jobGroup 3
// grant jobGroup 3 to the user, or call as an ADMIN_ROLE user
// after: ensure permission is held before invoking the protected action
LoginInfo info = JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify login + permission before invoking the protected action
Response<LoginInfo> r = XxlSsoHelper.loginCheckWithAttr(request);
if (r.isSuccess() && r.getData() != null
        && JobGroupPermissionUtil.hasJobGroupPermission(r.getData(), jobGroup)) {
    // proceed
} else {
    log.warn("denied: user lacks jobGroup {}", jobGroup);
}

Try / catch

try {
    LoginInfo info = JobGroupPermissionUtil.validJobGroupPermission(request, jobGroup);
} catch (RuntimeException e) {
    // permission/login failure; surface HTTP 403 to the caller
    log.warn("permission denied: {}", e.getMessage());
    throw new org.springframework.web.server.ResponseStatusException(org.springframework.http.HttpStatus.FORBIDDEN);
}

Prevention

When it happens

Trigger: Calling validJobGroupPermission(request, jobGroup) when loginCheckWithAttr reports failure, or when the user's 'jobGroups' extra-info list does not contain the requested jobGroup id. Triggered on protected admin endpoints (start/stop/trigger/log/etc. per job group).

Common situations: A non-admin user (no ADMIN_ROLE) attempts to operate on a job group they were not granted; SSO session expired so loginCheck returns non-success; misconfiguration of the user's jobGroups attribute in the identity store; the jobGroup id in the request does not match any granted group.

Related errors


AI-assisted analysis of xuxueli/xxl-job@e74c784f68 (2026-08-14). Data as JSON: /api/errors/ceb5aa15808e0323. Report an issue: GitHub.