wuyouzhuguli/SpringAll · error · UnapprovedClientAuthenticationException
clientId:{clientId}对应的信息不存在
Error message
clientId:{clientId}对应的信息不存在 What it means
UnapprovedClientAuthenticationException thrown when clientDetailsService.loadClientByClientId(clientId) returns null. The clientId came from decoding the Basic Authorization header. Note the message uses string concatenation ("clientId:" + clientId + ...) not a placeholder, so the literal '{clientId}' in the template is not templating — the actual clientId is interpolated.
Source
Thrown at 64.Spring-Security-OAuth2-Customize/src/main/java/cc/mrbird/security/handler/MyAuthenticationSucessHandler.java:53
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
// 1. 从请求头中获取 ClientId
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Basic ")) {
throw new UnapprovedClientAuthenticationException("请求头中无client信息");
}
String[] tokens = this.extractAndDecodeHeader(header, request);
String clientId = tokens[0];
String clientSecret = tokens[1];
TokenRequest tokenRequest = null;
// 2. 通过 ClientDetailsService 获取 ClientDetails
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
// 3. 校验 ClientId和 ClientSecret的正确性
if (clientDetails == null) {
throw new UnapprovedClientAuthenticationException("clientId:" + clientId + "对应的信息不存在");
} else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
throw new UnapprovedClientAuthenticationException("clientSecret不正确");
} else {
// 4. 通过 TokenRequest构造器生成 TokenRequest
tokenRequest = new TokenRequest(new HashMap<>(), clientId, clientDetails.getScope(), "custom");
}
// 5. 通过 TokenRequest的 createOAuth2Request方法获取 OAuth2Request
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
// 6. 通过 Authentication和 OAuth2Request构造出 OAuth2Authentication
OAuth2Authentication auth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
// 7. 通过 AuthorizationServerTokenServices 生成 OAuth2AccessToken
OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(auth2Authentication);
// 8. 返回 Token
log.info("登录成功");
response.setContentType("application/json;charset=UTF-8");View on GitHub (pinned to 614d2578d9)
Solutions
- Verify the clientId exists in the client store — for JDBC, SELECT * FROM oauth_client_details WHERE client_id = ?.
- Match the Basic header's clientId exactly to a registered client (mind trailing spaces from base64 decode).
- Confirm the ClientDetailsService bean your success handler autowires is the same one Spring Security OAuth2 configures (JDBC vs in-memory).
- Seed the client via the configured client store or add it in AuthorizationServerConfigurerAdapter.
Example fix
-- add the missing client (JDBC store)
INSERT INTO oauth_client_details
(client_id, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove)
VALUES
('my-client', '{noop}my-secret', 'all', 'password,refresh_token', null, null, 3600, 2592000, null, true); Defensive patterns
Strategy: validation
Validate before calling
// Validate client id format/whitelist before sending (basic guard).
const KNOWN_CLIENTS = new Set(['web','mobile']);
if (!KNOWN_CLIENTS.has(clientId)) { throw new Error('unknown clientId'); } Try / catch
try { await login(); }
catch (e) {
if (/对应的信息不存在/.test(e.message)) { /* check oauth_client_details, fix clientId */ }
else handleError(e);
} Prevention
- Seed oauth_client_details with every client your apps use.
- Keep the ClientDetailsService bean consistent (JDBC vs in-memory) across config.
- Trim decoded clientId to avoid whitespace mismatches.
When it happens
Trigger: The clientId in the Basic header does not exist in the ClientDetailsService backing store (often the oauth_client_details table for JDBC, or an in-memory client registry); the client was deleted; a typo in the client id.
Common situations: Using a JDBC ClientDetailsService but the row was never inserted; configured clients in-memory while the app wires a JDBC details service (or vice versa); copied sample credentials that do not match this deployment.
Related errors
- 请求头中无client信息
- clientSecret不正确
- Failed to decode basic authentication token
- Invalid basic authentication token
- 请在请求头中设置deviceId
AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14).
Data as JSON: /api/errors/2523543394727485.
Report an issue: GitHub.