wuyouzhuguli/SpringAll · error · BadCredentialsException

Invalid basic authentication token

Error message

Invalid basic authentication token

What it means

BadCredentialsException thrown in extractAndDecodeHeader when the decoded credential string contains no ':' delimiter — i.e. the original pre-base64 value was not in 'clientId:clientSecret' form. The code does token.indexOf(':') and rejects -1.

Source

Thrown at 64.Spring-Security-OAuth2-Customize/src/main/java/cc/mrbird/security/handler/MyAuthenticationSucessHandler.java:88

        log.info("登录成功");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(new ObjectMapper().writeValueAsString(token));
    }

    private String[] extractAndDecodeHeader(String header, HttpServletRequest request) {
        byte[] base64Token = header.substring(6).getBytes(StandardCharsets.UTF_8);

        byte[] decoded;
        try {
            decoded = Base64.getDecoder().decode(base64Token);
        } catch (IllegalArgumentException var7) {
            throw new BadCredentialsException("Failed to decode basic authentication token");
        }

        String token = new String(decoded, StandardCharsets.UTF_8);
        int delim = token.indexOf(":");
        if (delim == -1) {
            throw new BadCredentialsException("Invalid basic authentication token");
        } else {
            return new String[]{token.substring(0, delim), token.substring(delim + 1)};
        }
    }
}

View on GitHub (pinned to 614d2578d9)

Solutions

  1. Format the credentials as 'clientId:clientSecret' (colon-separated, id first) before base64-encoding.
  2. Double-check order: clientId before the colon, clientSecret after.
  3. If migrating from a system that used a different separator, normalize to colon.

Example fix

// before
// const basic = btoa('clientId' + 'clientSecret'); // no colon

// after
const basic = btoa('clientId' + ':' + 'clientSecret');
Defensive patterns

Strategy: validation

Validate before calling

// Guarantee the colon separator before encoding.
function basicHeader(id, secret) {
  if (id.includes(':') || secret.includes(':')) throw new Error('credentials must not contain ":"');
  return 'Basic ' + btoa(`${id}:${secret}`);
}

Try / catch

try { await login(); }
catch (e) {
  if (/Invalid basic authentication token/.test(e.message)) { /* ensure colon in pre-base64 value */ }
  else handleError(e);
}

Prevention

When it happens

Trigger: The base64-decoded payload lacks a colon: someone base64-encoded just the clientId, or 'secret:clientId' reversed, or a token without a separator.

Common situations: Client concatenated id and secret without the colon; reversed order; copied a bearer JWT into the Basic header.

Understand the failure class

Related errors


AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14). Data as JSON: /api/errors/4e98f9634d95f3c5. Report an issue: GitHub.