{"record":{"id":"4e98f9634d95f3c5","repo":"wuyouzhuguli/SpringAll","slug":"invalid-basic-authentication-token","errorCode":null,"errorMessage":"Invalid basic authentication token","messagePattern":"Invalid basic authentication token","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"64.Spring-Security-OAuth2-Customize/src/main/java/cc/mrbird/security/handler/MyAuthenticationSucessHandler.java","lineNumber":88,"sourceCode":"        log.info(\"登录成功\");\n        response.setContentType(\"application/json;charset=UTF-8\");\n        response.getWriter().write(new ObjectMapper().writeValueAsString(token));\n    }\n\n    private String[] extractAndDecodeHeader(String header, HttpServletRequest request) {\n        byte[] base64Token = header.substring(6).getBytes(StandardCharsets.UTF_8);\n\n        byte[] decoded;\n        try {\n            decoded = Base64.getDecoder().decode(base64Token);\n        } catch (IllegalArgumentException var7) {\n            throw new BadCredentialsException(\"Failed to decode basic authentication token\");\n        }\n\n        String token = new String(decoded, StandardCharsets.UTF_8);\n        int delim = token.indexOf(\":\");\n        if (delim == -1) {\n            throw new BadCredentialsException(\"Invalid basic authentication token\");\n        } else {\n            return new String[]{token.substring(0, delim), token.substring(delim + 1)};\n        }\n    }\n}\n","sourceCodeStart":70,"sourceCodeEnd":94,"githubUrl":"https://github.com/wuyouzhuguli/SpringAll/blob/614d2578d9495acf53cc02f2dee9c6131cc5e51a/64.Spring-Security-OAuth2-Customize/src/main/java/cc/mrbird/security/handler/MyAuthenticationSucessHandler.java#L70-L94","documentation":"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.","triggerScenarios":"The base64-decoded payload lacks a colon: someone base64-encoded just the clientId, or 'secret:clientId' reversed, or a token without a separator.","commonSituations":"Client concatenated id and secret without the colon; reversed order; copied a bearer JWT into the Basic header.","solutions":["Format the credentials as 'clientId:clientSecret' (colon-separated, id first) before base64-encoding.","Double-check order: clientId before the colon, clientSecret after.","If migrating from a system that used a different separator, normalize to colon."],"exampleFix":"// before\n// const basic = btoa('clientId' + 'clientSecret'); // no colon\n\n// after\nconst basic = btoa('clientId' + ':' + 'clientSecret');","handlingStrategy":"validation","validationCode":"// Guarantee the colon separator before encoding.\nfunction basicHeader(id, secret) {\n  if (id.includes(':') || secret.includes(':')) throw new Error('credentials must not contain \":\"');\n  return 'Basic ' + btoa(`${id}:${secret}`);\n}","typeGuard":null,"tryCatchPattern":"try { await login(); }\ncatch (e) {\n  if (/Invalid basic authentication token/.test(e.message)) { /* ensure colon in pre-base64 value */ }\n  else handleError(e);\n}","preventionTips":["Always format as clientId:clientSecret (id first, single colon).","Reject credentials containing ':' on the client side.","Use the standard helper rather than concatenation."],"tags":["oauth2","encoding","authentication","spring-security"],"backgroundTag":null,"analyzedSha":"614d2578d9495acf53cc02f2dee9c6131cc5e51a","analyzedAt":"2026-08-14T04:40:03.488Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}