]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
Add realm to HTTP Basic Authentication add-mandatory-realm-on-basic-auth 13511/head
authorMarcelo Trylesinski <marcelotryle@gmail.com>
Thu, 20 Mar 2025 11:10:41 +0000 (11:10 +0000)
committerMarcelo Trylesinski <marcelotryle@gmail.com>
Thu, 20 Mar 2025 11:10:41 +0000 (11:10 +0000)
fastapi/security/http.py
tests/test_security_http_basic_optional.py
tests/test_tutorial/test_security/test_tutorial006.py

index 9ab2df3c98e1e08a920de9439e78ecd65c2daada..1943cd56ab6a2af5c17bae7297422a3697df807f 100644 (file)
@@ -181,7 +181,7 @@ class HTTPBasic(HTTPBase):
     ):
         self.model = HTTPBaseModel(scheme="basic", description=description)
         self.scheme_name = scheme_name or self.__class__.__name__
-        self.realm = realm
+        self.realm = realm or ""
         self.auto_error = auto_error
 
     async def __call__(  # type: ignore
@@ -189,10 +189,8 @@ class HTTPBasic(HTTPBase):
     ) -> Optional[HTTPBasicCredentials]:
         authorization = request.headers.get("Authorization")
         scheme, param = get_authorization_scheme_param(authorization)
-        if self.realm:
-            unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
-        else:
-            unauthorized_headers = {"WWW-Authenticate": "Basic"}
+        # The "realm" is required, as per https://datatracker.ietf.org/doc/html/rfc7617#section-2.
+        unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
         if not authorization or scheme.lower() != "basic":
             if self.auto_error:
                 raise HTTPException(
index 9b6cb6c4554365a40cd78cadf05ac963fa0d3ccf..53bffe7e08a4e90a37085af3be1e65c28f5ee2e2 100644 (file)
@@ -37,7 +37,7 @@ def test_security_http_basic_invalid_credentials():
         "/users/me", headers={"Authorization": "Basic notabase64token"}
     )
     assert response.status_code == 401, response.text
-    assert response.headers["WWW-Authenticate"] == "Basic"
+    assert response.headers["WWW-Authenticate"] == 'Basic realm=""'
     assert response.json() == {"detail": "Invalid authentication credentials"}
 
 
@@ -46,7 +46,7 @@ def test_security_http_basic_non_basic_credentials():
     auth_header = f"Basic {payload}"
     response = client.get("/users/me", headers={"Authorization": auth_header})
     assert response.status_code == 401, response.text
-    assert response.headers["WWW-Authenticate"] == "Basic"
+    assert response.headers["WWW-Authenticate"] == 'Basic realm=""'
     assert response.json() == {"detail": "Invalid authentication credentials"}
 
 
index 40b413806201b5b43ef74314e3cfae25476e4f7e..7fbaec626d4de93d29074901832e1db89be9a05b 100644 (file)
@@ -32,7 +32,7 @@ def test_security_http_basic_no_credentials(client: TestClient):
     response = client.get("/users/me")
     assert response.json() == {"detail": "Not authenticated"}
     assert response.status_code == 401, response.text
-    assert response.headers["WWW-Authenticate"] == "Basic"
+    assert response.headers["WWW-Authenticate"] == 'Basic realm=""'
 
 
 def test_security_http_basic_invalid_credentials(client: TestClient):
@@ -40,7 +40,7 @@ def test_security_http_basic_invalid_credentials(client: TestClient):
         "/users/me", headers={"Authorization": "Basic notabase64token"}
     )
     assert response.status_code == 401, response.text
-    assert response.headers["WWW-Authenticate"] == "Basic"
+    assert response.headers["WWW-Authenticate"] == 'Basic realm=""'
     assert response.json() == {"detail": "Invalid authentication credentials"}
 
 
@@ -49,7 +49,7 @@ def test_security_http_basic_non_basic_credentials(client: TestClient):
     auth_header = f"Basic {payload}"
     response = client.get("/users/me", headers={"Authorization": auth_header})
     assert response.status_code == 401, response.text
-    assert response.headers["WWW-Authenticate"] == "Basic"
+    assert response.headers["WWW-Authenticate"] == 'Basic realm=""'
     assert response.json() == {"detail": "Invalid authentication credentials"}