jeecgboot/JeecgBoot · error · IllegalArgumentException
Sign签名校验失败!
Error message
Sign签名校验失败!
What it means
Thrown by SignatureCheckAspect when signAuthInterceptor.validateSignature() throws an IllegalArgumentException during signature validation, and the @SignatureCheck annotation's errorMessage() is set to the default 'Sign签名校验失败!'. In this case the original detailed error (from SignAuthInterceptor) is re-thrown as-is. If a custom errorMessage is configured, a new IllegalArgumentException with that custom message is thrown instead. This means the X-SIGN header is missing, the timestamp is expired, or the signature does not match the computed value.
Source
Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/aspect/SignatureCheckAspect.java:103
HttpServletRequest request = attributes.getRequest();
log.info("X-SIGN: {}, X-TIMESTAMP: {}", request.getHeader("X-SIGN"), request.getHeader("X-TIMESTAMP"));
try {
// 直接调用SignAuthInterceptor的验证逻辑
signAuthInterceptor.validateSignature(request, bodyParam);
log.info("AOP签名验证通过");
} catch (IllegalArgumentException e) {
// 使用注解中配置的错误消息,或者保留原始错误消息
String errorMessage = signatureCheck.errorMessage();
log.error("AOP签名验证失败: {}", e.getMessage());
if ("Sign签名校验失败!".equals(errorMessage)) {
// 如果是默认错误消息,使用原始的详细错误信息
throw e;
} else {
// 如果是自定义错误消息,使用自定义消息
throw new IllegalArgumentException(errorMessage, e);
}
} catch (Exception e) {
// 包装其他异常
String errorMessage = signatureCheck.errorMessage();
log.error("AOP签名验证异常: {}", e.getMessage());
throw new IllegalArgumentException(errorMessage, e);
}
}
}
View on GitHub (pinned to 96fb33f5ec)
Solutions
- Verify the signing secret key matches between client and server (jeecg.sign.secret configuration).
- Ensure the client sends both X-SIGN (computed signature) and X-TIMESTAMP headers.
- Check for clock skew — the server validates timestamp freshness; sync client and server clocks (NTP).
- Verify the signature algorithm matches — review SignAuthInterceptor.validateSignature() for the exact signing logic (parameter sorting, body inclusion, hash algorithm).
- Ensure no intermediary (gateway, proxy) modifies the request body or query parameters after signing.
Example fix
// Front-end: compute and send signature
const params = { id: 123, name: 'test', _t: Date.now() };
const signStr = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&');
const sign = CryptoJS.HmacSHA256(signStr, SIGN_SECRET).toString();
axios.post('/api/signed-endpoint', body, {
headers: {
'X-SIGN': sign,
'X-TIMESTAMP': params._t.toString()
}
});
// Verify: server sign secret == client sign secret
// Verify: parameter sorting and concatenation order match server logic Defensive patterns
Strategy: validation
Validate before calling
// Front-end: compute and verify signature before sending
const sortedParams = Object.keys(params).sort();
const signStr = sortedParams.map(k => `${k}=${params[k]}`).join('&');
const expectedSign = CryptoJS.HmacSHA256(signStr + timestamp, SIGN_SECRET).toString();
if (expectedSign !== computedSign) {
console.error('Signature mismatch — do not send');
} Try / catch
try {
// call signed API endpoint
} catch (error) {
if (error.response?.data?.message?.includes('签名校验失败')) {
log.error('Signature validation failed — check signing key and algorithm');
}
throw error;
} Prevention
- Ensure the signing secret matches exactly between client and server.
- Sync clocks (NTP) — timestamp validation rejects skewed requests.
- Review SignAuthInterceptor.validateSignature() for the exact signing algorithm (param sorting, body hashing).
- Ensure no proxy/gateway modifies request body or params after signing.
- Send both X-SIGN and X-TIMESTAMP headers on every signed request.
When it happens
Trigger: API request to a @SignatureCheck-annotated endpoint without the X-SIGN header; X-SIGN value does not match the HMAC/signature computed from the request parameters; X-TIMESTAMP is missing or outside the allowed time window; request body was modified after signing; wrong signing key configured on client vs server.
Common situations: Client and server have different signing secret keys; client-side signature algorithm does not match server-side (SignAuthInterceptor); timestamp clock skew between client and server exceeds the allowed window; request body is modified by a proxy/gateway after signing; front-end omits the X-SIGN or X-TIMESTAMP header.
Related errors
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/1a3c3a20810af995.
Report an issue: GitHub.