{"record":{"id":"79d1c151b3651869","repo":"paascloud/paascloud-master","slug":"clientsecret-79d1c1","errorCode":null,"errorMessage":"clientSecret不匹配:","messagePattern":"clientSecret不匹配:","errorType":"exception","errorClass":"UnapprovedClientAuthenticationException","httpStatus":null,"severity":"error","filePath":"paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/web/admin/UacUserLoginController.java","lineNumber":122,"sourceCode":"\t\ttry {\n\t\t\tPreconditions.checkArgument(org.apache.commons.lang3.StringUtils.isNotEmpty(accessToken), \"accessToken is null\");\n\t\t\tPreconditions.checkArgument(org.apache.commons.lang3.StringUtils.isNotEmpty(refreshToken), \"refreshToken is null\");\n\t\t\tString header = request.getHeader(HttpHeaders.AUTHORIZATION);\n\t\t\tif (header == null || !header.startsWith(BEARER_TOKEN_TYPE)) {\n\t\t\t\tthrow new UnapprovedClientAuthenticationException(\"请求头中无client信息\");\n\t\t\t}\n\t\t\tString[] tokens = RequestUtil.extractAndDecodeHeader(header);\n\t\t\tassert tokens.length == 2;\n\n\t\t\tString clientId = tokens[0];\n\t\t\tString clientSecret = tokens[1];\n\n\t\t\tClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);\n\n\t\t\tif (clientDetails == null) {\n\t\t\t\tthrow new UnapprovedClientAuthenticationException(\"clientId对应的配置信息不存在:\" + clientId);\n\t\t\t} else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {\n\t\t\t\tthrow new UnapprovedClientAuthenticationException(\"clientSecret不匹配:\" + clientId);\n\t\t\t}\n\n\t\t\ttoken = uacUserTokenService.refreshToken(accessToken, refreshToken, request);\n\t\t} catch (Exception e) {\n\t\t\tlogger.error(\"refreshToken={}\", e.getMessage(), e);\n\t\t\treturn WrapMapper.error();\n\t\t}\n\t\treturn WrapMapper.ok(token);\n\t}\n\n}","sourceCodeStart":104,"sourceCodeEnd":133,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/web/admin/UacUserLoginController.java#L104-L133","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)"],"exampleFix":"// before\nAuthorization: Basic Y2xpZW50SWQ6b2xkU2VjcmV0  // stale secret\n// after\nAuthorization: Basic Y2xpZW50SWQ6bmV3U2VjcmV0  // matches stored secret","handlingStrategy":"try-catch","validationCode":"// verify secret matches before calling\nif (!secret || secret !== storedSecretForClient(clientId)) { failFast('client secret mismatch for ' + clientId); }","typeGuard":null,"tryCatchPattern":"try { await refreshToken(token, headers); }\ncatch (e) {\n  if (String(e.message).includes('clientSecret不匹配')) {\n    // reload credentials from config/secret store and retry once\n  }\n}","preventionTips":["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"],"tags":["oauth2","credentials","authentication"],"backgroundTag":"missing-credentials","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}