{"record":{"id":"c2dadc592fb534e4","repo":"languagetool-org/languagetool","slug":"expected-basic-authentication-c2dadc","errorCode":null,"errorMessage":"Expected Basic Authentication","messagePattern":"Expected Basic Authentication","errorType":"http","errorClass":"AuthException","httpStatus":403,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/BasicAuthentication.java","lineNumber":32,"sourceCode":" * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301\n * USA\n */\npackage org.languagetool.server;\n\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Base64;\n\npublic class BasicAuthentication {\n  private final String user;\n  private final String password;\n\n  public BasicAuthentication(String authHeader) {\n    if (!authHeader.startsWith(\"Basic \")) {\n      throw new AuthException(\"Expected Basic Authentication\");\n    }\n    String authEncoded = authHeader.substring(\"Basic \".length());\n    Charset cs = StandardCharsets.UTF_8;\n    ByteBuffer authDecodedBytes = ByteBuffer.wrap(Base64.getDecoder().decode(authEncoded.getBytes(cs)));\n    String authDecoded = cs.decode(authDecodedBytes).toString();\n    String[] authParts = authDecoded.split(\":\", 2);\n    if (authParts.length != 2 || authParts[0].trim().isEmpty() || authParts[1].trim().isEmpty()) {\n      throw new AuthException(\"Expected Basic Authentication\");\n    }\n    user = authParts[0];\n    password = authParts[1];\n  }\n\n  public String getUser() {\n    return user;\n  }\n\n  public String getPassword() {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/BasicAuthentication.java#L14-L50","documentation":"Constructor guard in BasicAuthentication: the supplied Authorization header did not start with 'Basic ', so it is either missing or uses another auth scheme, and cannot be decoded as basic credentials.","triggerScenarios":"Sending an Authorization header with another scheme (Bearer, Token) or malformed casing/content, or an empty header, to an endpoint protected by this check.","commonSituations":"Clients configured for token/bearer auth against a server expecting basic auth; proxies stripping the scheme; hand-built headers missing the 'Basic ' prefix and space.","solutions":["Send 'Authorization: Basic <base64(user:password)>' exactly, with the 'Basic ' prefix.","Switch the client's auth scheme to basic authentication.","Verify no middleware rewrites or strips the Authorization header.","Check capitalization/prefix handling; the check is case-sensitive ('Basic ' with capital B)."],"exampleFix":"// before\nheaders.set(\"Authorization\", \"Bearer eyJhbGci...\")\n// after\nString cred = Base64.getEncoder().encodeToString(\"user:pass\".getBytes(StandardCharsets.UTF_8));\nheaders.set(\"Authorization\", \"Basic \" + cred);","handlingStrategy":"try-catch","validationCode":"if (!authHeader || !authHeader.startsWith('Basic ')) {\n  throw new Error('Authorization header must use Basic scheme');\n}","typeGuard":"function isBasicAuthHeader(h) { return typeof h === 'string' && h.startsWith('Basic '); }","tryCatchPattern":"try {\n  BasicAuthentication auth = new BasicAuthentication(request.getHeader(\"Authorization\"));\n} catch (AuthException e) {\n  response.sendError(401, \"Provide Authorization: Basic <base64(user:pass)>\");\n}","preventionTips":["Configure clients for basic auth, not bearer, against servers that require it.","Always build the header as 'Basic ' + base64(user:password).","Test the header with curl -u user:pass."],"tags":["http","authentication","security"],"backgroundTag":"authentication-required","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}