Malformed JWT in an app request returns 500 instead of 401

Description

Problem

When a wrong token is sent to the app (lifecycle callbacks, iframes, REST), a request with a malformed JWT ends in a server error. The same happens when the signature part is missing, when the header names an encryption algorithm instead of a signing algorithm, or when the payload is not JSON. Each such request logs an ERROR and raises an alert on the error channel, even though the client is at fault. This traffic comes mostly from scanners, so the noise hides real errors. Authentication is shared, so this affects Approval Path and the other Connect apps that use it.

Cause

The token is parsed only after a database connection is opened. Only a few parse errors were treated as a bad token; everything else was handled as an internal app error.

Steps to reproduce

  1. Send a request to any app endpoint that needs authentication, with jwt=header.payload in the query.

Actual behavior

HTTP 500. The log has an ERROR Invalid serialized unsecured/JWS/JWE object: Missing second delimiter.

Expected behavior

HTTP 401 with a WARN log entry. No ERROR and no error channel alert.

Out of scope

Other client errors during authentication still return 500 (e.g. app install with a non-existent key id).

Acceptance criteria

  • A token without all parts (e.g. header.payload) returns 401.

  • A token with an encryption algorithm in the header (e.g. RSA-OAEP) returns 401.

  • A token whose payload is not JSON returns 401.

  • A malformed token does not use a database connection.

  • None of these requests log an ERROR.

  • Requests with a valid token and requests with no token behave as before.