elunez/eladmin · error · BadRequestException

非法的 Bean,请重新输入!

Error message

非法的 Bean,请重新输入!

What it means

QuartzJobController.checkBean rejects a quartz job whose beanName is not present in SpringBeanHolder.getAllServiceBeanName() — i.e. not a Spring bean defined with @Service. This is a deliberate security hardening (comments in the code explain it): arbitrary bean names previously allowed invoking beans like jdbcTemplate via reflection and executing arbitrary SQL. Only beans in the service-bean whitelist can be scheduled.

Source

Thrown at eladmin-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java:138

    public ResponseEntity<Object> executionQuartzJob(@PathVariable Long id){
        quartzJobService.execution(quartzJobService.findById(id));
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Log("删除定时任务")
    @ApiOperation("删除定时任务")
    @DeleteMapping
    @PreAuthorize("@el.check('timing:del')")
    public ResponseEntity<Object> deleteQuartzJob(@RequestBody Set<Long> ids){
        quartzJobService.delete(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    private void checkBean(String beanName){
        // 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
        // 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
        if(!SpringBeanHolder.getAllServiceBeanName().contains(beanName)){
            throw new BadRequestException("非法的 Bean,请重新输入!");
        }
    }
}

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Ensure the target class is annotated @Service (not @Component/@Configuration) so it lands in the service-bean name list.
  2. Use the exact bean name (default: class simple name with lowercase first letter, e.g. 'visitorTask') in the job form.
  3. Confirm the class's package is under the @SpringBootApplication scan path or explicitly scanned.

Example fix

// before
@Component("myTask")
public class MyTask { public void run(){...} }
// after
@Service("myTask")
public class MyTask { public void run(){...} }
Defensive patterns

Strategy: validation

Validate before calling

// before submitting, confirm the bean is a registered service bean
Set<String> names = SpringBeanHolder.getAllServiceBeanName();
if (!names.contains(job.getBeanName())) {
    throw new IllegalArgumentException("beanName 必须是 @Service bean: " + job.getBeanName());
}

Type guard

boolean isServiceBean(String name) {
    return name != null && SpringBeanHolder.getAllServiceBeanName().contains(name);
}

Prevention

When it happens

Trigger: Creating or updating a quartz job with a beanName that is not a registered @Service bean: typo in the name, a bean annotated @Component instead of @Service, a bean in a package not scanned, or an attempted attack using bean names like 'jdbcTemplate'.

Common situations: Writing a custom scheduled task class and forgetting @Service; renaming the bean class without updating the job config; plugin/task classes in a module excluded from component scanning; penetration-test payloads targeting the old unvalidated behavior.

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/47c529df4815537e. Report an issue: GitHub.