Auth handler per connection #1473
-
I'm currently trying out httpx as part of a WinRM based library which has a unique requirement for encryption over HTTP. The authentication is typically import httpx
class NegotiateAuth(httpx.Auth):
def __init__(self, username, password):
self.username = username
self.password = None
self.context = None
def sync_auth_flow(self, request):
response = yield request
if response.status_code != 401:
return
self.context = MySecContext(self.username, self.password)
out_token = self.context.step()
while not self.context.complete:
request.headers['Authorization'] = out_token
# send the request with the auth token and get the response
response = yield request
# Feed the token back into the context until it's set up
def wrap(self, data);
return self.context.wrap(data)
def unwrap(self, data):
return self.context.unwrap(data)
class WinRMClient:
def __init__(self):
auth = NegotiateAuth('username', 'password')
client = httpx.AsyncClient(auth=auth)
async def send(self, data):
# set up initial auth with blank request
if not self.auth.context:
await self.client.post('endpoint', content=b'')
enc_data = self.client.auth.wrap(data)
resp = await self.client.post('endpoint', content=enc_data)
return self.client.auth.unwrap(resp.content) This works fine if I've only ever got 1 connection being used in the pool as the context in the What I'm hoping to find out is a way to:
Do you have any ideas how I could potentially implement these requirements? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 9 replies
-
Hey @davidbgk This is a very interesting scenario. I believe the transport route is the most promising. The "wrap / unwrap" thingy you do there for example screams for "wrap the request / response stream" at the transport level. :) But I wouldn't do subclassing. Instead I think you might be able to get something working by composing with an existing transport, and then wrapping things however is necessary to accommodate your auth scheme. You might not even need to modify the pool, and instead do the tracking of origins inside your own transport. I can draft some code snippets to help you out with this intuition later if you'd like. :) |
Beta Was this translation helpful? Give feedback.
Hey @davidbgk
This is a very interesting scenario.
I believe the transport route is the most promising. The "wrap / unwrap" thingy you do there for example screams for "wrap the request / response stream" at the transport level. :)
But I wouldn't do subclassing. Instead I think you might be able to get something working by composing with an existing transport, and then wrapping things however is necessary to accommodate your auth scheme. You might not even need to modify the pool, and instead do the tracking of origins inside your own transport.
I can draft some code snippets to help you out with this intuition later if you'd like. :)