You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It would be nice to support HTTP Digest authentication.
It could be easily implemented in the _handshake.py.handshake() by checking for the 401 status and the Authorization response header. I made a very dirty hack just to test it and works well (this supports only the most simple Digest auth).
--- _handshake.py 2022-05-11 11:24:42.203249509 +0200
+++ new/_handshake.py 2022-05-12 10:28:12.773080587 +0200
@@ -19,6 +19,7 @@
import hashlib
import hmac
import os
+import www_authenticate
from base64 import encodebytes as base64encode
from http import client as HTTPStatus
from ._cookiejar import SimpleCookieJar
@@ -33,7 +34,8 @@
VERSION = 13
SUPPORTED_REDIRECT_STATUSES = (HTTPStatus.MOVED_PERMANENTLY, HTTPStatus.FOUND, HTTPStatus.SEE_OTHER,)
-SUCCESS_STATUSES = SUPPORTED_REDIRECT_STATUSES + (HTTPStatus.SWITCHING_PROTOCOLS,)
+SUPPORTED_UNAUTHORIZED_STATUSES = (HTTPStatus.UNAUTHORIZED,)
+SUCCESS_STATUSES = SUPPORTED_REDIRECT_STATUSES + SUPPORTED_UNAUTHORIZED_STATUSES + (HTTPStatus.SWITCHING_PROTOCOLS,)
CookieJar = SimpleCookieJar()
@@ -55,8 +57,30 @@
dump("request header", header_str)
status, resp = _get_resp_headers(sock)
+ if status in SUPPORTED_UNAUTHORIZED_STATUSES:
+ auth_header = www_authenticate.parse(resp.get('www-authenticate'))
+ digest = auth_header.get('digest')
+ if digest:
+ h1 = hashlib.md5(f"{username}:{digest['realm']}:{password}".encode('utf-8')).hexdigest()
+ h2 = hashlib.md5(f"GET:{url}".encode('utf-8')).hexdigest()
+ rs = h1 + ":" + digest['nonce'] + ":" + h2
+ response = hashlib.md5(rs.encode('utf-8')).hexdigest()
+
+ h = options.get('header', [])
+ h += [f'Authorization: Digest username="{username}",realm={digest["realm"]},nonce={digest["nonce"]},uri={url},nc=00000001,response={response}']
+ options['header'] = h
+ headers, key = _get_handshake_headers(resource, url, hostname, port, options)
+
+ header_str = "\r\n".join(headers)
+ send(sock, header_str)
+ dump("request header", header_str)
+
+ status, resp = _get_resp_headers(sock)
+
+
if status in SUPPORTED_REDIRECT_STATUSES:
return handshake_response(status, resp, None)
+
success, subproto = _validate(resp, key, options.get("subprotocols"))
if not success:
raise WebSocketException("Invalid WebSocket Header")
The text was updated successfully, but these errors were encountered:
Nice work! We can combine this with an older example from issue #470 and make a PR out of it. I am unlikely to prioritize this in the next few weeks since I am not using an HTTP auth proxy, so if someone wants to submit a PR, it would be very welcome.
I don't often implement proxies with digest auth so I want to crowdsource an answer for which common proxy I should test the HTTP digest auth implementation against. Please add your comment here to vote for a proxy. I want to implement this feature in parallel with adding a proxy into the CI unit tests, because right now the CI does not use an actual proxy during testing and therefore the code coverage don't fully cover the proxy code, which should be fixed.
It would be nice to support HTTP Digest authentication.
It could be easily implemented in the _handshake.py.handshake() by checking for the 401 status and the Authorization response header. I made a very dirty hack just to test it and works well (this supports only the most simple Digest auth).
The text was updated successfully, but these errors were encountered: