jeecgboot/JeecgBoot · error · JeecgBootException

signature签名已过期(超过五分钟)

Error message

signature签名已过期(超过五分钟)

What it means

Thrown by checkSignValid when System.currentTimeMillis() minus the supplied timestamp exceeds 5*60*1000 ms (5 minutes). This is a replay-protection window: a captured signature cannot be reused after 5 minutes. There is no negative/future check, so clocks ahead are tolerated; only an old timestamp triggers this.

Source

Thrown at jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java:208

     * @param signature
     * @param timestamp
     * @return
     */
    protected void checkSignValid(String appkey, String signature, String timestamp) {
        if (!StringUtils.hasText(appkey)) {
            throw new JeecgBootException("appkey为空");
        }
        if (!StringUtils.hasText(signature)) {
            throw new JeecgBootException("signature为空");
        }
        if (!StringUtils.hasText(timestamp)) {
            throw new JeecgBootException("timastamp时间戳为空");
        }
        if (!timestamp.matches("[0-9]*")) {
            throw new JeecgBootException("timastamp时间戳不合法");
        }
        if (System.currentTimeMillis() - Long.parseLong(timestamp) > 5 * 60 * 1000) {
            throw new JeecgBootException("signature签名已过期(超过五分钟)");
        }
    }

    /**
     * 认证信息核验
     * @param appKey
     * @param signature
     * @param timestamp
     * @param openApiAuth
     * @return
     * @throws Exception
     */
    protected void checkSignature(String appKey, String signature, String timestamp, OpenApiAuth openApiAuth) {
        if(openApiAuth==null){
            throw new JeecgBootException("不存在认证信息");
        }

        if(!appKey.equals(openApiAuth.getAk())){

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Synchronize client and server clocks via NTP/chrony; keep drift under 1 minute.
  2. Generate the timestamp immediately before each request rather than caching signed URLs.
  3. If the legitimate deployment has known skew, the 5-minute constant must be widened in code (no config property exists).

Example fix

// before: long ts = cachedTimestamp;  // generated minutes ago
// after:  long ts = System.currentTimeMillis();  // fresh per request
//         String sig = md5(ak + sk + ts);
Defensive patterns

Strategy: validation

Validate before calling

// Sign as late as possible and assert freshness before sending
String ts = String.valueOf(System.currentTimeMillis());
String sig = md5(appkey + sk + ts);
long skew = Math.abs(System.currentTimeMillis() - Long.parseLong(ts));
if (skew > 60_000L) { /* resync clock / regenerate */ }

Prevention

When it happens

Trigger: Client clock is more than 5 minutes behind the server; the request was replayed/queued > 5 min after signing; container clock skew between client pod and server pod.

Common situations: NTP drift on client or server; long network/CPU delays before the filter processes the request; clients caching pre-signed requests.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/df15f37941878ca2. Report an issue: GitHub.