mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-04-18 07:35:22 +01:00
Return 401 for non-Basic Authorization headers on /auth endpoint (#6612)
aiohttp's BasicAuth.decode() raises ValueError for any non-Basic auth method (e.g. Bearer tokens). This propagated as an unhandled exception, causing a 500 response instead of the expected 401 Unauthorized. Catch the ValueError in _process_basic() and raise HTTPUnauthorized with the WWW-Authenticate realm header so clients get a proper 401 response. Fixes SUPERVISOR-BFG Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -49,7 +49,10 @@ class APIAuth(CoreSysAttributes):
|
|||||||
|
|
||||||
Return a coroutine.
|
Return a coroutine.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
auth = BasicAuth.decode(request.headers[AUTHORIZATION])
|
auth = BasicAuth.decode(request.headers[AUTHORIZATION])
|
||||||
|
except ValueError as err:
|
||||||
|
raise HTTPUnauthorized(headers=REALM_HEADER) from err
|
||||||
return self.sys_auth.check_login(addon, auth.login, auth.password)
|
return self.sys_auth.check_login(addon, auth.login, auth.password)
|
||||||
|
|
||||||
def _process_dict(
|
def _process_dict(
|
||||||
|
|||||||
@@ -330,6 +330,18 @@ async def test_auth_basic_auth_failure(
|
|||||||
assert resp.status == 401
|
assert resp.status == 401
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("api_client", [TEST_ADDON_SLUG], indirect=True)
|
||||||
|
async def test_auth_bearer_token_returns_401(
|
||||||
|
api_client: TestClient, install_addon_ssh: Addon
|
||||||
|
):
|
||||||
|
"""Test that a Bearer token in Authorization header returns 401, not 500."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
"/auth", headers={"Authorization": "Bearer sometoken123"}
|
||||||
|
)
|
||||||
|
assert "Basic realm" in resp.headers[WWW_AUTHENTICATE]
|
||||||
|
assert resp.status == 401
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("api_client", ["local_example"], indirect=True)
|
@pytest.mark.parametrize("api_client", ["local_example"], indirect=True)
|
||||||
async def test_auth_addon_no_auth_access(
|
async def test_auth_addon_no_auth_access(
|
||||||
api_client: TestClient, install_addon_example: Addon
|
api_client: TestClient, install_addon_example: Addon
|
||||||
|
|||||||
Reference in New Issue
Block a user