paascloud/paascloud-master · error · UnapprovedClientAuthenticationException
clientSecret不匹配:
Error message
clientSecret不匹配:
What it means
UnapprovedClientAuthenticationException with message 'clientSecret不匹配:' + clientId thrown by UacUserLoginController.refreshToken when the decoded clientSecret from the Basic auth header does not equal the stored clientDetails.getClientSecret(). The clientId was found but credentials fail verification.
Solutions
- Update the client secret in the caller's configuration to match the stored secret in oauth_client_details
- Re-encode the Basic header correctly: base64(clientId:secret) with no stray whitespace
- If the secret must change, update the stored secret for the client in the database to the new value
- Verify no environment mismatch (secret set for dev client used against prod client record)
Example fix
// before Authorization: Basic Y2xpZW50SWQ6b2xkU2VjcmV0 // stale secret // after Authorization: Basic Y2xpZW50SWQ6bmV3U2VjcmV0 // matches stored secret
Defensive patterns
Strategy: try-catch
Validate before calling
// verify secret matches before calling
if (!secret || secret !== storedSecretForClient(clientId)) { failFast('client secret mismatch for ' + clientId); } Try / catch
try { await refreshToken(token, headers); }
catch (e) {
if (String(e.message).includes('clientSecret不匹配')) {
// reload credentials from config/secret store and retry once
}
} Prevention
- Rotate client secrets in sync between server store and clients
- Trim whitespace/newlines when copying secrets
- Load secrets from a secret manager, not pasted literals
- Re-encode the Basic header after any credential change
When it happens
Trigger: POST to refreshToken with a Basic Authorization header where base64-decoded clientId:secret has a secret that differs from the stored secret for that client (string comparison via StringUtils.equals fails).
Common situations: Secret rotated on the server but the frontend still ships the old one; secret copied with trailing whitespace/newline; using the client secret of a different client; plaintext vs encoded secret mismatch after a config change.
Related errors
AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10).
Data as JSON: /api/errors/79d1c151b3651869.
Report an issue: GitHub.
Appendix: source
Thrown at paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/web/admin/UacUserLoginController.java:122
try {
Preconditions.checkArgument(org.apache.commons.lang3.StringUtils.isNotEmpty(accessToken), "accessToken is null");
Preconditions.checkArgument(org.apache.commons.lang3.StringUtils.isNotEmpty(refreshToken), "refreshToken is null");
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header == null || !header.startsWith(BEARER_TOKEN_TYPE)) {
throw new UnapprovedClientAuthenticationException("请求头中无client信息");
}
String[] tokens = RequestUtil.extractAndDecodeHeader(header);
assert tokens.length == 2;
String clientId = tokens[0];
String clientSecret = tokens[1];
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
if (clientDetails == null) {
throw new UnapprovedClientAuthenticationException("clientId对应的配置信息不存在:" + clientId);
} else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
throw new UnapprovedClientAuthenticationException("clientSecret不匹配:" + clientId);
}
token = uacUserTokenService.refreshToken(accessToken, refreshToken, request);
} catch (Exception e) {
logger.error("refreshToken={}", e.getMessage(), e);
return WrapMapper.error();
}
return WrapMapper.ok(token);
}
}View on GitHub (pinned to 781281a950)