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

  1. Update the client secret in the caller's configuration to match the stored secret in oauth_client_details
  2. Re-encode the Basic header correctly: base64(clientId:secret) with no stray whitespace
  3. If the secret must change, update the stored secret for the client in the database to the new value
  4. 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

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)