Skip to content

Commit 1aa6c93

Browse files
zandbeltclaude
andcommitted
return a 401 instead of a 500 when a token is rejected
liboauth2 up to 2.3.0 does not set the "status_code" out-parameter of oauth2_token_verify for a failure it detects locally, i.e. for any JWT that is expired, carries a bad signature or fails "iss"/"aud"/"nbf" validation. It then keeps the 0 it was initialized with, which is returned here as an Apache return code and thus means OK; with no user set Apache logs "AH00027: No authentication done but request not allowed without authentication" and returns a 500. An introspection endpoint answering "active": false similarly left the 200 of that successful call behind. Invert the test so that no non-error status can escape: only a 5xx is relayed as-is, anything else results in a 401 with a WWW-Authenticate header, as it did before 4.1.0 started leveraging the status code. liboauth2 >= 2.3.1 sets the status code itself, but keeping the check here also covers the older versions that are already packaged. closes #94 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent e67fb4e commit 1aa6c93

2 files changed

Lines changed: 25 additions & 4 deletions

File tree

‎ChangeLog‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
08/01/2026
2+
- return a 401 instead of a 500 when a token is rejected without an HTTP status
3+
code being set by liboauth2, which is the case for any locally detected JWT
4+
verification failure i.e. expiry, signature mismatch, "iss"/"aud"/"nbf"
5+
validation; the unset status code (0) was returned to Apache as OK, without a
6+
user being set, upon which Apache logs "AH00027: No authentication done but
7+
request not allowed without authentication" and returns a 500; only a 5xx is
8+
now relayed as-is, anything else results in a 401 with a WWW-Authenticate
9+
header; liboauth2 >= 2.3.1 sets the status code itself, this covers older
10+
versions as well
11+
thanks @smanolache; closes #94
12+
113
05/23/2026
214
- depend on liboauth2 >= 2.2.1 with updated so.1 link
315
- release 4.2.0

‎src/mod_oauth2.c‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,21 @@ static int oauth2_request_handler(oauth2_cfg_source_token_t *cfg,
114114

115115
if (oauth2_token_verify(ctx->log, ctx->request, verify, source_token,
116116
&json_token, &status_code) == false) {
117-
if ((status_code >= 400) && (status_code < 500)) {
117+
// a server error is relayed as-is; anything else results in a
118+
// 401 with a WWW-Authenticate header, including a status code
119+
// that was left unset (0) by an older liboauth2, since
120+
// returning that to Apache would signal OK without a user
121+
// being set, which results in a 500 (AH00027)
122+
if ((status_code >= 500) && (status_code < 600)) {
123+
rv = status_code;
124+
} else {
118125
rv = oauth2_apache_return_www_authenticate(
119-
cfg, ctx, status_code, OAUTH2_ERROR_INVALID_TOKEN,
126+
cfg, ctx,
127+
((status_code >= 400) && (status_code < 500))
128+
? status_code
129+
: HTTP_UNAUTHORIZED,
130+
OAUTH2_ERROR_INVALID_TOKEN,
120131
"Token could not be verified.");
121-
} else {
122-
rv = status_code;
123132
}
124133
goto end;
125134
}

0 commit comments

Comments
 (0)