Add realm to HTTP Basic Authentication

This commit is contained in:
Marcelo Trylesinski 2025-03-20 11:10:41 +00:00
parent 4e40e1e85d
commit c07ff9234a
3 changed files with 8 additions and 10 deletions

View File

@ -181,7 +181,7 @@ class HTTPBasic(HTTPBase):
): ):
self.model = HTTPBaseModel(scheme="basic", description=description) self.model = HTTPBaseModel(scheme="basic", description=description)
self.scheme_name = scheme_name or self.__class__.__name__ self.scheme_name = scheme_name or self.__class__.__name__
self.realm = realm self.realm = realm or ""
self.auto_error = auto_error self.auto_error = auto_error
async def __call__( # type: ignore async def __call__( # type: ignore
@ -189,10 +189,8 @@ class HTTPBasic(HTTPBase):
) -> Optional[HTTPBasicCredentials]: ) -> Optional[HTTPBasicCredentials]:
authorization = request.headers.get("Authorization") authorization = request.headers.get("Authorization")
scheme, param = get_authorization_scheme_param(authorization) scheme, param = get_authorization_scheme_param(authorization)
if self.realm: # The "realm" is required, as per https://datatracker.ietf.org/doc/html/rfc7617#section-2.
unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'} unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
else:
unauthorized_headers = {"WWW-Authenticate": "Basic"}
if not authorization or scheme.lower() != "basic": if not authorization or scheme.lower() != "basic":
if self.auto_error: if self.auto_error:
raise HTTPException( raise HTTPException(

View File

@ -37,7 +37,7 @@ def test_security_http_basic_invalid_credentials():
"/users/me", headers={"Authorization": "Basic notabase64token"} "/users/me", headers={"Authorization": "Basic notabase64token"}
) )
assert response.status_code == 401, response.text 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"} assert response.json() == {"detail": "Invalid authentication credentials"}
@ -46,7 +46,7 @@ def test_security_http_basic_non_basic_credentials():
auth_header = f"Basic {payload}" auth_header = f"Basic {payload}"
response = client.get("/users/me", headers={"Authorization": auth_header}) response = client.get("/users/me", headers={"Authorization": auth_header})
assert response.status_code == 401, response.text 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"} assert response.json() == {"detail": "Invalid authentication credentials"}

View File

@ -32,7 +32,7 @@ def test_security_http_basic_no_credentials(client: TestClient):
response = client.get("/users/me") response = client.get("/users/me")
assert response.json() == {"detail": "Not authenticated"} assert response.json() == {"detail": "Not authenticated"}
assert response.status_code == 401, response.text 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): 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"} "/users/me", headers={"Authorization": "Basic notabase64token"}
) )
assert response.status_code == 401, response.text 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"} 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}" auth_header = f"Basic {payload}"
response = client.get("/users/me", headers={"Authorization": auth_header}) response = client.get("/users/me", headers={"Authorization": auth_header})
assert response.status_code == 401, response.text 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"} assert response.json() == {"detail": "Invalid authentication credentials"}