{"record":{"id":"a8d1c4dfaa0e21ac","repo":"apereo/cas","slug":"unknown-authorization-header-type","errorCode":null,"errorMessage":"Unknown authorization header type","messagePattern":"Unknown authorization header type","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-heimdall/src/main/java/org/apereo/cas/heimdall/engine/DefaultAuthorizationPrincipalParser.java","lineNumber":88,"sourceCode":"        }\n        return PrincipalFactoryUtils.newPrincipalFactory().createPrincipal(claims.getSubject(), principalAttributes);\n    }\n\n    protected JWTClaimsSet parseAuthorizationHeader(final String authorizationHeader) throws Throwable {\n        if (authorizationHeader.startsWith(\"Basic \")) {\n            val token = Strings.CI.removeStart(authorizationHeader, \"Basic \");\n            return buildClaimSetFromAuthentication(token);\n        }\n        if (authorizationHeader.startsWith(\"Bearer \")) {\n            val token = Strings.CI.removeStart(authorizationHeader, \"Bearer \");\n            val claims = parseOidcIdToken(token)\n                .or(() -> parseJwtAccessToken(token))\n                .or(() -> getJwtClaimsSetFromAccessToken(token))\n                .or(() -> parseJwtAuthorization(token))\n                .orElseThrow(() -> new AuthenticationException(\"Unable to parse and verify token\"));\n            return validateClaims(claims);\n        }\n        throw new AuthenticationException(\"Unknown authorization header type\");\n    }\n\n    protected Optional<JWTClaimsSet> parseJwtAuthorization(final String token){\n        try {\n            val clientIdInAssertion = OAuth20Utils.extractClientIdFromToken(token);\n            LOGGER.debug(\"Client id retrieved from ID token is [{}]\", clientIdInAssertion);\n            val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(\n                accessTokenJwtBuilder.getObject().getServicesManager(),\n                clientIdInAssertion, OidcRegisteredService.class);\n\n            val jsonWebKeys = getJsonWebKeyToVerifyAssertion(registeredService);\n            val verifiedAssertion = verifyAssertion(token, jsonWebKeys);\n            val claims = JwtClaims.parse(verifiedAssertion);\n\n            val baseOidcUrl = accessTokenJwtBuilder.getObject().getCasProperties()\n                .getServer().getPrefix() + '/' + OidcConstants.BASE_OIDC_URL + '/';\n            val jwtClaimsSetVerifier = new DefaultJWTClaimsVerifier<>(\n                CollectionUtils.wrapSet(","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-heimdall/src/main/java/org/apereo/cas/heimdall/engine/DefaultAuthorizationPrincipalParser.java#L70-L106","documentation":"DefaultAuthorizationPrincipalParser (Heimdall) inspects the Authorization header to decide its token type: Bearer access token, JWT, or signed authorization assertion. If the header does not fit any recognized type, it throws AuthenticationException 'Unknown authorization header type'.","triggerScenarios":"parseAuthorizationHeader (via claims()) receives a header whose scheme/prefix is not one of the handled forms, so all parse branches are skipped and the final throw is reached.","commonSituations":"Client sends a custom scheme (e.g. 'Token abc') instead of Bearer; header contains an opaque key or API key that is not a JWT; missing 'Bearer ' prefix so the token is misparsed; sending the wrong kind of credential to the Heimdall endpoint.","solutions":["Send a standard 'Authorization: Bearer <token>' header with a JWT or supported access token","Check the token is well-formed (three dot-separated JWT segments) and not base64/percent-encoded oddly","Confirm you are calling the endpoint intended for that credential type (Heimdall policies expect principal-bearing tokens)","Inspect DefaultAuthorizationPrincipalParser for the accepted header formats and match your client accordingly"],"exampleFix":"// before\nAuthorization: Apitoken abc123\n// after\nAuthorization: Bearer eyJhbGciOiJSUzI1NiIs...","handlingStrategy":"validation","validationCode":"String header = request.getHeader(\"Authorization\");\nif (header == null || !header.startsWith(\"Bearer \") || !header.substring(7).contains(\".\")) {\n    throw new IllegalArgumentException(\"Authorization header must be 'Bearer <jwt>'\");\n}","typeGuard":"static boolean isBearerJwt(String header) {\n    return header != null && header.startsWith(\"Bearer \")\n        && header.substring(7).split(\"\\\\.\").length == 3;\n}","tryCatchPattern":"try {\n    return parser.claims(token);\n} catch (AuthenticationException e) {\n    // return 401 with WWW-Authenticate: Bearer\n}","preventionTips":["Always use the standard Bearer scheme","Validate token shape client-side before sending","Use the correct credential type for the endpoint"],"tags":["authorization","http-header","jwt","bearer-token"],"backgroundTag":"authentication-required","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}