Skip to content

Commit

Permalink
Make redirect URL auth take precedence over input auth in client
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre-Louis Peeters committed Oct 11, 2024
1 parent 496391e commit 549279a
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES/9436.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Authentication provided by a redirect now takes precedence over provided ``auth`` when making requests with the client -- by :user:`PLPeeters`.
4 changes: 3 additions & 1 deletion aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,9 @@ async def _request(
"credentials encoded in URL"
)

if auth is None:
# Override the auth with the one from the URL only if we
# have no auth, or if we got an auth from a redirect URL
if auth is None or (history and auth_from_url is not None):
auth = auth_from_url

if auth is None and (
Expand Down
7 changes: 7 additions & 0 deletions docs/client_advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ argument. An instance of :class:`BasicAuth` can be passed in like this::
async with ClientSession(auth=auth) as session:
...

Note that if the request is redirected and the redirect URL contains
credentials, those credentials will supersede any previously set credentials.
In other words, if ``http://user@example.com`` redirects to
``http://other_user@example.com``, the second request will be authenticated
as ``other_user``. Providing both the ``auth`` parameter and authentication in
the *initial* URL will result in a :exc:`ValueError`.

For other authentication flows, the ``Authorization`` header can be set
directly::

Expand Down
9 changes: 9 additions & 0 deletions tests/test_client_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -2927,8 +2927,14 @@ async def test_creds_in_auth_and_url() -> None:
await session.close()


@pytest.mark.parametrize(
["check_redirect_auth_precedence"],
([False], [True]),
ids=("redirect auth clash allowed", "redirect auth precedence"),
)
async def test_creds_in_auth_and_redirect_url(
create_server_for_url_and_handler: Callable[[URL, Handler], Awaitable[TestServer]],
check_redirect_auth_precedence: bool,
) -> None:
url_from = URL("http://example.com")
url_to = URL("http://user@example.com")
Expand Down Expand Up @@ -2984,6 +2990,9 @@ async def close(self) -> None:
assert str(resp.url) == "http://example.com"
assert resp.status == 200

if check_redirect_auth_precedence:
assert resp.request_info.headers.get("authorization") == "Basic dXNlcjo="


@pytest.fixture
def create_server_for_url_and_handler(
Expand Down

0 comments on commit 549279a

Please sign in to comment.