pythongssapi / httpx-gssapi Goto Github PK
View Code? Open in Web Editor NEWA GSSAPI authentication handler for Python's HTTPX
License: Other
A GSSAPI authentication handler for Python's HTTPX
License: Other
Would it be possible to publish the package on conda forge?
Hi all. Is this is working implementation?
I have a windows host running python 3.6. I've have a kerberos ticket through the usual windows AD mechanisms, but have also installed the MIT msi from https://web.mit.edu/KERBEROS/dist/
I can see my personal and computer's tickets with klist, but a quick test throws an error:
import httpx
from httpx_gssapi import HTTPSPNEGOAuth, OPTIONAL
gssapi_auth = HTTPSPNEGOAuth(mutual_authentication=OPTIONAL)
r = httpx.get("https://localserver/api/v1.0/public/table/version_mapping", verify=False, auth=gssapi_auth)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_api.py", line 170, in get
trust_env=trust_env,
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_api.py", line 96, in request
allow_redirects=allow_redirects,
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_client.py", line 601, in request
request, auth=auth, allow_redirects=allow_redirects, timeout=timeout,
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_client.py", line 621, in send
request, auth=auth, timeout=timeout, allow_redirects=allow_redirects,
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_client.py", line 648, in send_handling_redirects
request, auth=auth, timeout=timeout, history=history
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_client.py", line 693, in send_handling_auth
raise exc from None
File "C:\code\gits\uthh-api\.venv\lib\site-packages\httpx\_client.py", line 688, in send_handling_auth
next_request = auth_flow.send(response)
File "c:\code\gits\httpx-gssapi\httpx_gssapi\gssapi_.py", line 113, in auth_flow
yield from self.handle_response(response)
File "c:\code\gits\httpx-gssapi\httpx_gssapi\gssapi_.py", line 121, in handle_response
response = yield self.handle_401(response)
File "c:\code\gits\httpx-gssapi\httpx_gssapi\gssapi_.py", line 138, in handle_401
request = self.authenticate_user(response)
File "c:\code\gits\httpx-gssapi\httpx_gssapi\gssapi_.py", line 229, in authenticate_user
auth_header = self.generate_request_header(host, response)
File "c:\code\gits\httpx-gssapi\httpx_gssapi\gssapi_.py", line 218, in generate_request_header
gss_resp = self.context[host].step(token)
File "<decorator-gen-15>", line 2, in step
File "C:\code\gits\uthh-api\.venv\lib\site-packages\gssapi\_utils.py", line 169, in check_last_err
return func(self, *args, **kwargs)
File "<decorator-gen-5>", line 2, in step
File "C:\code\gits\uthh-api\.venv\lib\site-packages\gssapi\_utils.py", line 129, in catch_and_return_token
return func(self, *args, **kwargs)
File "C:\code\gits\uthh-api\.venv\lib\site-packages\gssapi\sec_contexts.py", line 521, in step
return self._initiator_step(token=token)
File "C:\code\gits\uthh-api\.venv\lib\site-packages\gssapi\sec_contexts.py", line 542, in _initiator_step
token)
File "gssapi\raw\sec_contexts.pyx", line 245, in gssapi.raw.sec_contexts.init_sec_context
File "gssapi\raw\misc.pyx", line 219, in gssapi.raw.misc.GSSErrorRegistry.__call__
File "gssapi\raw\misc.pyx", line 275, in gssapi.raw.misc.GSSError.__init__
File "gssapi\raw\misc.pyx", line 326, in gssapi.raw.misc.GSSError.gen_message
File "gssapi\raw\misc.pyx", line 294, in gssapi.raw.misc.GSSError.get_all_statuses
AttributeError: module 'locale' has no attribute 'LC_MESSAGES'
Using pytest, I've tried to create a mock fixture for an app written with FastAPI/HTTPX (FastAPI is an interface microservice receiving requests, and forwarding onto a backend service using an HTTPX Async client).
The fixture and unit test
from httpx_gssapi import HTTPSPNEGOAuth
from pytest_httpx import HTTPXMock
from unittest.mock import Mock
class TestClient(object):
@ pytest.fixture
def test_client(self, test_settings):
"""Returns a test-configured client to use in tests"""
test_client = MyClient(test_settings)
test_client._auth = Mock(spec=HTTPSPNEGOAuth)
return test_client
@pytest.mark.asyncio
async def test_client_get_id(self, test_app, test_client, httpx_mock: HTTPXMock):
# Mocks
httpx_mock.add_response(
url="http://test/id?path=foo&selectedFields=Id",
json={"Id": "TEST"}
)
async with AsyncClient(app=test_app, base_url="http://test") as ac:
id = await test_client._get_id(ac, "foo")
assert id == 'TEST'
MyCllient
has the auth
set as a member, using the following prod defaults, which I thought the mock replacing in the fixture would be enough for things to "just work".
self._auth = HTTPSPNEGOAuth(
mutual_authentication=OPTIONAL,
opportunistic_auth=True,
delegate=False)
Within the function being tested, a get request is being made using a HTTPSPNEGOAuth
auth object, with an httpx.AsyncClient
instance
response = await client.get(url, params=params, auth=self._auth) # Line that is failing in the test
I receive the error:
self = <httpx.AsyncClient object at 0x00000232160A6640>
request = <Request('GET', 'http://test/id?path=foo&selectedFields=Id')>
auth = <Mock spec='HTTPSPNEGOAuth' id='2414147621552'>
timeout = Timeout(timeout=5.0), allow_redirects = True, history = []
async def _send_handling_auth(
self,
request: Request,
auth: Auth,
timeout: Timeout,
allow_redirects: bool,
history: typing.List[Response],
) -> Response:
auth_flow = auth.async_auth_flow(request)
try:
request = await auth_flow.__anext__()
for hook in self._event_hooks["request"]:
await hook(request)
while True:
response = await self._send_handling_redirects(
request,
timeout=timeout,
allow_redirects=allow_redirects,
history=history,
)
try:
try:
next_request = await auth_flow.asend(response)
except StopAsyncIteration:
return response
response.history = list(history)
await response.aread()
request = next_request
history.append(response)
except Exception as exc:
await response.aclose()
raise exc
finally:
> await auth_flow.aclose()
E TypeError: object Mock can't be used in 'await' expression
I treid swapping the Mock
for an AsyncMock
in the fixture:
@ pytest.fixture
def test_client(self, test_settings):
"""Returns a test-configured client to use in tests"""
test_client = MyClient(test_settings)
test_client._auth = AsyncMock(spec=HTTPSPNEGOAuth) # AsyncMock used
return test_client
Which gives a similar error still:
self = <httpx.AsyncClient object at 0x000001D67640A3D0>
request = <AsyncMock name='mock.async_auth_flow().__anext__()' id='2020620739584'>
auth = <AsyncMock spec='HTTPSPNEGOAuth' id='2020617927120'>
timeout = Timeout(timeout=5.0), allow_redirects = True, history = []
async def _send_handling_auth(
self,
request: Request,
auth: Auth,
timeout: Timeout,
allow_redirects: bool,
history: typing.List[Response],
) -> Response:
auth_flow = auth.async_auth_flow(request)
try:
request = await auth_flow.__anext__()
for hook in self._event_hooks["request"]:
await hook(request)
while True:
response = await self._send_handling_redirects(
request,
timeout=timeout,
allow_redirects=allow_redirects,
history=history,
)
try:
try:
next_request = await auth_flow.asend(response)
except StopAsyncIteration:
return response
response.history = list(history)
await response.aread()
request = next_request
history.append(response)
except Exception as exc:
await response.aclose()
raise exc
finally:
> await auth_flow.aclose()
E TypeError: object MagicMock can't be used in 'await' expression
I'm not sure where to take it from here to get the auth object mocked out correctly for use with pytest.
@JacobHenner I'm on it this time ;)
httpx 0.24.0 was released at the beginning of April, but this library is marked as compatible with httpx>=0.16,<0.24
. Please extend compatibility to include 0.24.0.
Similar to HTTP error 401 + Authorization headers sometimes not the server, but a proxy needs authorization.
It's using HTTP error 407 and Proxy-Authorization headers.
httpx==0.25.0 was released on 2023-09-11.
httpx-gssapi is marked as compatible with httpx>=0.16,<0.25
, which excludes 0.25.0:
Line 28 in 69d14ba
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.