requests-kerberos icon indicating copy to clipboard operation
requests-kerberos copied to clipboard

force_preemptive=True is only preemptive the first time

Open gconklin opened this issue 2 years ago • 1 comments

When setting force_preemptive=True, it looks like only the first request gets an immediate 200 and all other following requests get a 401, and then a 200.

I'm essentially doing this:

import requests
from requests_kerberos import HTTPKerberosAuth
from requests_kerberos.exceptions import KerberosExchangeError

class Thing:
    def __init__(self):
        self.session = requests.Session()
        self.session.auth = HTTPKerberosAuth(force_preemptive=True)

    def get(self, url):
        return self.session.get(url)

t = Thing()
t.get("https://hostname/")
t.get("https://hostname/")
First request:
DEBUG:requests_kerberos.kerberos_:HTTPKerberosAuth: Preemptive Authorization header: Negotiate ...
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): hostname:443
DEBUG:urllib3.connectionpool:https://hostname:443 "GET / HTTP/1.1" 200 None
DEBUG:requests_kerberos.kerberos_:handle_other(): Handling: 200
DEBUG:requests_kerberos.kerberos_:handle_other(): Authenticating the server
DEBUG:requests_kerberos.kerberos_:authenticate_server(): Authenticate header:
DEBUG:requests_kerberos.kerberos_:authenticate_server(): returning <Response [200]>
DEBUG:requests_kerberos.kerberos_:handle_other(): returning <Response [200]>
DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [200]>

Next request:
DEBUG:urllib3.connectionpool:https://hostname:443 "GET / HTTP/1.1" 401 381
DEBUG:requests_kerberos.kerberos_:handle_401(): Handling: 401
DEBUG:requests_kerberos.kerberos_:authenticate_user(): Authorization header: Negotiate ...
DEBUG:urllib3.connectionpool:https://hostname:443 "GET / HTTP/1.1" 200 None
DEBUG:requests_kerberos.kerberos_:authenticate_user(): returning <Response [200]>
DEBUG:requests_kerberos.kerberos_:handle_401(): returning <Response [200]>
DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [200]>
DEBUG:requests_kerberos.kerberos_:handle_response() has seen 0 401 responses
DEBUG:requests_kerberos.kerberos_:handle_other(): Handling: 200
DEBUG:requests_kerberos.kerberos_:handle_other(): returning <Response [200]>
DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [200]>

requests==2.27.1 requests-kerberos==0.14.0

gconklin avatar Jul 08 '22 16:07 gconklin

This is because of the following reason:

Currently force_preemptive flag sends the Authorization header only for the first call and not for subsequent calls. This is because Authorization header is preemptively sent only if the request is not authenticated. The status of authentication is stored as auth_done instance variable. Since all the HTTP calls use the same instance of HTTPKerberosAuth class the auth_done instance variable is set to True after first successful authentication and thus Authorization header is not set preemptively after that. Raised a PR to fix this issue https://github.com/requests/requests-kerberos/pull/183

chamakuri-vineel avatar Sep 01 '23 19:09 chamakuri-vineel