Skip to content

Commit cbc48c3

Browse files
authored
Return 401 Unauthorized when using json/url encoded auth fails (#5844)
When authentication using JSON payload or URL encoded payload fails, use the generic HTTP response code 401 Unauthorized instead of 400 Bad Request. This is a more appropriate response code for authentication errors and is consistent with the behavior of other authentication methods.
1 parent 11e3701 commit cbc48c3

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

supervisor/api/auth.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,18 @@ async def auth(self, request: web.Request) -> bool:
9292
# Json
9393
if request.headers.get(CONTENT_TYPE) == CONTENT_TYPE_JSON:
9494
data = await request.json(loads=json_loads)
95-
return await self._process_dict(request, addon, data)
95+
if not await self._process_dict(request, addon, data):
96+
raise HTTPUnauthorized()
97+
return True
9698

9799
# URL encoded
98100
if request.headers.get(CONTENT_TYPE) == CONTENT_TYPE_URL:
99101
data = await request.post()
100-
return await self._process_dict(request, addon, data)
102+
if not await self._process_dict(request, addon, data):
103+
raise HTTPUnauthorized()
104+
return True
101105

106+
# Advertise Basic authentication by default
102107
raise HTTPUnauthorized(headers=REALM_HEADER)
103108

104109
@api_process

tests/api/test_auth.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from datetime import UTC, datetime, timedelta
44
from unittest.mock import AsyncMock, MagicMock, patch
55

6+
from aiohttp.hdrs import WWW_AUTHENTICATE
67
from aiohttp.test_utils import TestClient
78
import pytest
89

@@ -166,8 +167,8 @@ async def test_auth_json_invalid_credentials(
166167
resp = await api_client.post(
167168
"/auth", json={"username": "test", "password": "wrong"}
168169
)
169-
# Do we really want the API to return 400 here?
170-
assert resp.status == 400
170+
assert WWW_AUTHENTICATE not in resp.headers
171+
assert resp.status == 401
171172

172173

173174
@pytest.mark.parametrize("api_client", [TEST_ADDON_SLUG], indirect=True)
@@ -213,8 +214,8 @@ async def test_auth_urlencoded_failure(
213214
data="username=test&password=fail",
214215
headers={"Content-Type": "application/x-www-form-urlencoded"},
215216
)
216-
# Do we really want the API to return 400 here?
217-
assert resp.status == 400
217+
assert WWW_AUTHENTICATE not in resp.headers
218+
assert resp.status == 401
218219

219220

220221
@pytest.mark.parametrize("api_client", [TEST_ADDON_SLUG], indirect=True)
@@ -225,7 +226,7 @@ async def test_auth_unsupported_content_type(
225226
resp = await api_client.post(
226227
"/auth", data="something", headers={"Content-Type": "text/plain"}
227228
)
228-
# This probably should be 400 here for better consistency
229+
assert "Basic realm" in resp.headers[WWW_AUTHENTICATE]
229230
assert resp.status == 401
230231

231232

0 commit comments

Comments
 (0)