Skip to content

Unable to authenticate on macOS - how to confirm it's pulling cached credentials? #193

Open

Description

@victorhooi

I'm trying to use requests-kerberos on macOS, and can't seem to authenticate properly. I'm a Kerberos newbie, so it's very possible I'm missing something basic here.

I use kinit to authenticate myself and populate the credential cache. I then used klist to verify that I have a cached TGT there:

❯ klist -A
Credentials cache: API:F56611A6-CC9E-447F-9438-E264BAF2ECFD
        Principal: john.smith@FOOBAR.COM

  Issued                Expires               Principal
May  8 14:06:10 2025  May  9 00:06:10 2025  krbtgt/FOOBAR.COM@FOOBAR.COM

I did notice that the "Credentials cache" specifies "API:" as the location, rather than say, a temporary file somewhere - but from my research I believe that's normal/expected on macOS as it's no longer file-backed. (Source: jcmturner/gokrb5#412)

When I make my request to the remote server with requests-kerberos, requests.text simply contains "Unauthorised". Sample code:

def main():
    logging.basicConfig(level=logging.DEBUG)
    kerberos_auth = HTTPKerberosAuth(principal="krbtgt/foobar.COM@foobar.COM")
    r = requests.get("http://proxy1.orthrus.byted.org:8080/api/v1/gss/list", auth=kerberos_auth)
    print(r.text)

I turned on verbose logging (logging.basicConfig(level=logging.DEBUG)), and I tried again, full output is below:

However, it's a little unclear to me if requests-kerberos is actually successfully pulling the cached credentials or not.

Is there some way to verify that it's actually pulling them, and presenting them, or is there something else I'm missing here?

DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): proxy1.foobar.org:8080
DEBUG:urllib3.connectionpool:http://proxy1.foobar.org:8080 "GET /api/v1/gss/list HTTP/1.1" 401 15
DEBUG:requests_kerberos.kerberos_:handle_401(): Handling: 401
ERROR:requests_kerberos.kerberos_:generate_request_header(): ctx init failed:
Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 363, in __init__
    gssapi_credential = _get_gssapi_credential(
                        ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 120, in _get_gssapi_credential
    gss_cred = gssapi.Credentials(name=principal, usage=usage, mechs=[mech])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 77, in __new__
    res = cls.acquire(name, lifetime, mechs, usage,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 163, in acquire
    res = rcreds.acquire_cred(name, lifetime,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "gssapi/raw/creds.pyx", line 127, in gssapi.raw.creds.acquire_cred
gssapi.raw.exceptions.MissingCredentialsError: Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_kerberos/kerberos_.py", line 213, in generate_request_header
    self._context[host] = ctx = spnego.client(
                                ^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 169, in client
    return _new_context(
           ^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 84, in _new_context
    return proxy(
           ^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 370, in __init__
    raise SpnegoError(base_error=gss_err, context_msg="Getting GSSAPI credential") from gss_err
spnego.exceptions.NoCredentialError: SpnegoError (7): Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown, Context: Getting GSSAPI credential
ERROR:requests_kerberos.kerberos_:SpnegoError (7): Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown, Context: Getting GSSAPI credential
Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 363, in __init__
    gssapi_credential = _get_gssapi_credential(
                        ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 120, in _get_gssapi_credential
    gss_cred = gssapi.Credentials(name=principal, usage=usage, mechs=[mech])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 77, in __new__
    res = cls.acquire(name, lifetime, mechs, usage,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 163, in acquire
    res = rcreds.acquire_cred(name, lifetime,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "gssapi/raw/creds.pyx", line 127, in gssapi.raw.creds.acquire_cred
gssapi.raw.exceptions.MissingCredentialsError: Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_kerberos/kerberos_.py", line 213, in generate_request_header
    self._context[host] = ctx = spnego.client(
                                ^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 169, in client
    return _new_context(
           ^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 84, in _new_context
    return proxy(
           ^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 370, in __init__
    raise SpnegoError(base_error=gss_err, context_msg="Getting GSSAPI credential") from gss_err
spnego.exceptions.NoCredentialError: SpnegoError (7): Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown, Context: Getting GSSAPI credential
DEBUG:requests_kerberos.kerberos_:handle_401(): returning <Response [401]>
DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [401]>
DEBUG:requests_kerberos.kerberos_:handle_response() has seen 0 401 responses
DEBUG:requests_kerberos.kerberos_:handle_401(): Handling: 401
ERROR:requests_kerberos.kerberos_:generate_request_header(): ctx init failed:
Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 363, in __init__
    gssapi_credential = _get_gssapi_credential(
                        ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 120, in _get_gssapi_credential
    gss_cred = gssapi.Credentials(name=principal, usage=usage, mechs=[mech])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 77, in __new__
    res = cls.acquire(name, lifetime, mechs, usage,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 163, in acquire
    res = rcreds.acquire_cred(name, lifetime,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "gssapi/raw/creds.pyx", line 127, in gssapi.raw.creds.acquire_cred
gssapi.raw.exceptions.MissingCredentialsError: Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_kerberos/kerberos_.py", line 213, in generate_request_header
    self._context[host] = ctx = spnego.client(
                                ^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 169, in client
    return _new_context(
           ^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 84, in _new_context
    return proxy(
           ^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 370, in __init__
    raise SpnegoError(base_error=gss_err, context_msg="Getting GSSAPI credential") from gss_err
spnego.exceptions.NoCredentialError: SpnegoError (7): Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown, Context: Getting GSSAPI credential
ERROR:requests_kerberos.kerberos_:SpnegoError (7): Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown, Context: Getting GSSAPI credential
Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 363, in __init__
    gssapi_credential = _get_gssapi_credential(
                        ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 120, in _get_gssapi_credential
    gss_cred = gssapi.Credentials(name=principal, usage=usage, mechs=[mech])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 77, in __new__
    res = cls.acquire(name, lifetime, mechs, usage,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/creds.py", line 163, in acquire
    res = rcreds.acquire_cred(name, lifetime,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "gssapi/raw/creds.pyx", line 127, in gssapi.raw.creds.acquire_cred
gssapi.raw.exceptions.MissingCredentialsError: Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_kerberos/kerberos_.py", line 213, in generate_request_header
    self._context[host] = ctx = spnego.client(
                                ^^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 169, in client
    return _new_context(
           ^^^^^^^^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/auth.py", line 84, in _new_context
    return proxy(
           ^^^^^^
  File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 370, in __init__
    raise SpnegoError(base_error=gss_err, context_msg="Getting GSSAPI credential") from gss_err
spnego.exceptions.NoCredentialError: SpnegoError (7): Major (458752):  No credentials were supplied, or the credentials were unavailable or inaccessible., Minor (0): unknown mech-code 0 for mech unknown, Context: Getting GSSAPI credential
DEBUG:requests_kerberos.kerberos_:handle_401(): returning <Response [401]>
DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [401]>
DEBUG:requests_kerberos.kerberos_:handle_response() has seen 1 401 responses
DEBUG:requests_kerberos.kerberos_:handle_response(): returning 401 <Response [401]>
Unauthorised.



Process finished with exit code 0

Activity

  1. jborean93 commented on May 8, 2025

    @jborean93
    Contributor

    kerberos_auth = HTTPKerberosAuth(principal="krbtgt/foobar.COM@foobar.COM")

    Try just principal='john.smith@FOOBAR.COM' as the krbtgt/... principal is the target/service principal used to retrieve the TGT and not the actual client principal in the cache you wish to use. Technically a cache can have multiple principal if the ccache type supports it so specifying the client principal to use is a way to pick which once you want.

  2. victorhooi commented on May 8, 2025

    @victorhooi
    Author

    @jborean93 thanks for the suggestion!

    OK, I've edited that line to set the principal as suggested:

    kerberos_auth = HTTPKerberosAuth(principal="john.smith@EXAMPLE.COM")
    

    Running it again - the error message is different - A parameter was malformed Miscellaneous failure (see text), Minor (0): Success - is that a good thing and it's further along in the process? =)

    However, I'm not sure what ot make of that error. Have you seen that before, or any ideas?

    DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): proxy1.example.org:8080
    DEBUG:urllib3.connectionpool:http://proxy1.example.org:8080 "GET /api/v1/gss/list HTTP/1.1" 401 15
    DEBUG:requests_kerberos.kerberos_:handle_401(): Handling: 401
    DEBUG:spnego._gss:GSSAPI step input: 
    DEBUG:spnego._gss:GSSAPI step output: YIIDTQYJKoZIhvcSAQICAQBuggM8MIIDOKADAgEFoQMCAQ6iBwMFACAAAACjggFrYYIBZzCCAWOgAwIBBaEPGw1CWVRFREFOQ0UuQ09NoiswKaADAgEDoSIwIBsESFRUUBsYcHJveHkxLm9ydGhydXMuYnl0ZWQub3Jno4IBHDCCARigAwIBEaEDAgEBooIBCgSCAQYGj9UgUQ+flkzSvm+XJZw7DV3yJgDOK4bHTImkdA0fcBoiVk1YjqZSQVbTvhWHryCKX1/NsLKOHQieEsp1wshU2+QGVLPWJcf97vT+q2EbXshtaglk74s4AdWIWgQ0ojsSuY1fMSkOq/JsM15uBfauxjgRCJ4jx8hreEdfEphwNxa4h1TMckIwaf44ny78dnrr1EIeQCPFlSywUR7PiebpiEZp+rlKl+wra3qV278jlQcYhUPH4dS78UuL9L1z6FswDUQLWfbDrgpWOjkVI79bf+RaAw60Vk0gL2iFgkUgWwC8Y3owcl3DAMg1PWPmMP/QA0zibv4XaqYIjKUXUuJF9Ql/szgZpIIBsjCCAa6gAwIBEqKCAaUEggGhC3LG6uPuvlBM0+Rl6ucc2JcR7qcnmkgmNmRS9N/70UK/OaKW544/6/ZkwakLNqrRrhEF16ENfr+rrYffQAhEIWcCpkdhO7EFVgRF0V8Uwvcwv0B7Q/fcVjj2y9m6o5yhdxuTwAyd/D+Rvsh35C20eEaMKmxQH1Z/Pjos/IACOIbR08eNdzz7fra5isIraQn8CYU3cbrhef5rFA5tG+eLdHvQel4wzJJyoo5uyU33mf2FqQ0MsAsK9SvZSfaNtKw0WkuSMbBJcGhnyQ8qI3rN8GAD6yNX+5FbJSUXbuo+EFdh9C2uEOSTl3B3zSR0dXdBa5fK/mBP+AvWwqCtotOBJVtmTL6qKmzSdoy+qrYnhLuy6sDnNJuEhf5OMfyYLPwxXHxeJt+hgHupvkeWhDrzza5c7Xde0PVpe51i45ZXRTVCraZtu1+LlQycPCt52gcvOhSCMvWmiFkBusJPxexJdXtIlcyWiWs9OmDnmQxIiEHIlqG5Z5CASnN3Rv/v/xymGQV/pATa/VoOe0c6bLzjXgaB4c+jtzvQCnauEkH0I6DZ
    DEBUG:requests_kerberos.kerberos_:authenticate_user(): Authorization header: Negotiate YIIDTQYJKoZIhvcSAQICAQBuggM8MIIDOKADAgEFoQMCAQ6iBwMFACAAAACjggFrYYIBZzCCAWOgAwIBBaEPGw1CWVRFREFOQ0UuQ09NoiswKaADAgEDoSIwIBsESFRUUBsYcHJveHkxLm9ydGhydXMuYnl0ZWQub3Jno4IBHDCCARigAwIBEaEDAgEBooIBCgSCAQYGj9UgUQ+flkzSvm+XJZw7DV3yJgDOK4bHTImkdA0fcBoiVk1YjqZSQVbTvhWHryCKX1/NsLKOHQieEsp1wshU2+QGVLPWJcf97vT+q2EbXshtaglk74s4AdWIWgQ0ojsSuY1fMSkOq/JsM15uBfauxjgRCJ4jx8hreEdfEphwNxa4h1TMckIwaf44ny78dnrr1EIeQCPFlSywUR7PiebpiEZp+rlKl+wra3qV278jlQcYhUPH4dS78UuL9L1z6FswDUQLWfbDrgpWOjkVI79bf+RaAw60Vk0gL2iFgkUgWwC8Y3owcl3DAMg1PWPmMP/QA0zibv4XaqYIjKUXUuJF9Ql/szgZpIIBsjCCAa6gAwIBEqKCAaUEggGhC3LG6uPuvlBM0+Rl6ucc2JcR7qcnmkgmNmRS9N/70UK/OaKW544/6/ZkwakLNqrRrhEF16ENfr+rrYffQAhEIWcCpkdhO7EFVgRF0V8Uwvcwv0B7Q/fcVjj2y9m6o5yhdxuTwAyd/D+Rvsh35C20eEaMKmxQH1Z/Pjos/IACOIbR08eNdzz7fra5isIraQn8CYU3cbrhef5rFA5tG+eLdHvQel4wzJJyoo5uyU33mf2FqQ0MsAsK9SvZSfaNtKw0WkuSMbBJcGhnyQ8qI3rN8GAD6yNX+5FbJSUXbuo+EFdh9C2uEOSTl3B3zSR0dXdBa5fK/mBP+AvWwqCtotOBJVtmTL6qKmzSdoy+qrYnhLuy6sDnNJuEhf5OMfyYLPwxXHxeJt+hgHupvkeWhDrzza5c7Xde0PVpe51i45ZXRTVCraZtu1+LlQycPCt52gcvOhSCMvWmiFkBusJPxexJdXtIlcyWiWs9OmDnmQxIiEHIlqG5Z5CASnN3Rv/v/xymGQV/pATa/VoOe0c6bLzjXgaB4c+jtzvQCnauEkH0I6DZ
    DEBUG:urllib3.connectionpool:http://proxy1.example.org:8080 "GET /api/v1/gss/list HTTP/1.1" 401 15
    DEBUG:requests_kerberos.kerberos_:authenticate_user(): returning <Response [401]>
    DEBUG:requests_kerberos.kerberos_:handle_401(): returning <Response [401]>
    DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [401]>
    DEBUG:requests_kerberos.kerberos_:handle_response() has seen 0 401 responses
    DEBUG:requests_kerberos.kerberos_:handle_401(): Handling: 401
    DEBUG:spnego._gss:GSSAPI step input: oRQwEqADCgEBoQsGCSqGSIb3EgECAg==
    ERROR:requests_kerberos.kerberos_:generate_request_header(): ctx step failed:
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_context.py", line 68, in wrapper
        return func(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 464, in step
        out_token = self._context.step(in_token)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 165, in check_last_err
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 584, in step
        return self._initiator_step(token=token)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
        res = rsec_contexts.init_sec_context(self._target_name, self._creds,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
    gssapi.raw.exceptions.MalformedParameterError: Major (51183616): A parameter was malformed Miscellaneous failure (see text), Minor (0): Success
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_kerberos/kerberos_.py", line 229, in generate_request_header
        gss_response = ctx.step(in_token=negotiate_resp_value)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_context.py", line 71, in wrapper
        raise SpnegoError(base_error=native_err, context_msg=context) from native_err
    spnego.exceptions.SpnegoError: SpnegoError (4294967295): Major (51183616): A parameter was malformed Miscellaneous failure (see text), Minor (0): Success, Context: Processing security token
    ERROR:requests_kerberos.kerberos_:SpnegoError (4294967295): Major (51183616): A parameter was malformed Miscellaneous failure (see text), Minor (0): Success, Context: Processing security token
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_context.py", line 68, in wrapper
        return func(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_gss.py", line 464, in step
        out_token = self._context.step(in_token)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 165, in check_last_err
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 584, in step
        return self._initiator_step(token=token)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
        res = rsec_contexts.init_sec_context(self._target_name, self._creds,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
    gssapi.raw.exceptions.MalformedParameterError: Major (51183616): A parameter was malformed Miscellaneous failure (see text), Minor (0): Success
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_kerberos/kerberos_.py", line 229, in generate_request_header
        gss_response = ctx.step(in_token=negotiate_resp_value)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/spnego/_context.py", line 71, in wrapper
        raise SpnegoError(base_error=native_err, context_msg=context) from native_err
    spnego.exceptions.SpnegoError: SpnegoError (4294967295): Major (51183616): A parameter was malformed Miscellaneous failure (see text), Minor (0): Success, Context: Processing security token
    DEBUG:requests_kerberos.kerberos_:handle_401(): returning <Response [401]>
    DEBUG:requests_kerberos.kerberos_:handle_response(): returning <Response [401]>
    DEBUG:requests_kerberos.kerberos_:handle_response() has seen 1 401 responses
    DEBUG:requests_kerberos.kerberos_:handle_response(): returning 401 <Response [401]>
    Unauthorised.
    
    
    
    Process finished with exit code 0
    
  3. victorhooi commented on May 9, 2025

    @victorhooi
    Author

    Just another datapoint - we have an official CLI tool that hits the same endpoint, and authenticates successfully (as you'd expect). I was able to take a packet capture from that tool.

    If I take the HTTP Authorization header from that capture, I can use that in a HTTP client (e.g. Yaak, Curl etc), and it also works there as well. (However, it does stop working after a while, I assume due to expiry?)

    Here is a sample HTTP Authorization header from the official client - which works, and you can use to reply requests (for a short time):

    Authorization: Negotiate YIICgAYGKwYBBQUCoIICdDCCAnCgDTALBgkqhkiG9xIBAgKiggJdBIICWWCCAlUGCSqGSIb3EgECAgEAboICRDCCAkCgAwIBBaEDAgEOogcDBQAAAAAAo4IBeWGCAXUwggFxoAMCAQWhDxsNQllURURBTkNFLkNPTaI5MDegAwIBAaEwMC4bBEhUVFAbJmF1dGh6ZC1wcm94eS1pMThuLm9ydGhydXMtdXMuYnl0ZWQub3Jno4IBHDCCARigAwIBEaEDAgEBooIBCgSCAQYiPkg/ayM3OqPf7sWtraw0OlNH2IhdLzILj2mUtCUeOe4FpCugQlMLw5W2IgOlWsj6Jkq8bX//6WMKqokGDvbXnK6B0KCfd3hnDh9+s/soXj0IR8YpfpiNb21lQ+q0NPDjlPjxHLJsXJoMizFjQxl9fdU+i+afH2bj4zF9l6ng9Gan9rOUn5J6sALQsOdLFDw27DWO6GvL2JAS9fFe6lTd/bKUIlqKSANrHs7Ngk9UJVrHKvuVM9NQeYFLH3vprD2wPmum2gs2xyr4focEQ/TIyYmjRoPSEKfr7xNXDfWFvsBVDw3sKxw/Ad0n1YmwrutCL+OmS1pCRydJoGbx0PDL+kbkl3I1pIGtMIGqoAMCARKhAwIBAaKBnQSBmlAfkIqiUqL7qfxk9eRzoKxPFJjq9RHWpq7tQx8QyArYQYUEZTFOeMMqiDCaDpeUcaeFwxu+4tOpT4v6bYodc1W31KucMry/9o4Odw8bxqILR1TIeHc98w6wmXk8fcElsPDrT8MnOcPC/ZOyTq42yb9v5hOxxu/OgrO6b7+KGPN2LOHTkZculi7UCfoJO74CxJI1I7yzs8R+8ns=
    
    

    And here is the one from the debug line in requests-kerberos:

    DEBUG:requests_kerberos.kerberos_:authenticate_user(): Authorization header: Negotiate YIIDTQYJKoZIhvcSAQICAQBuggM8MIIDOKADAgEFoQMCAQ6iBwMFACAAAACjggFrYYIBZzCCAWOgAwIBBaEPGw1CWVRFREFOQ0UuQ09NoiswKaADAgEDoSIwIBsESFRUUBsYcHJveHkxLm9ydGhydXMuYnl0ZWQub3Jno4IBHDCCARigAwIBEaEDAgEBooIBCgSCAQYGj9UgUQ+flkzSvm+XJZw7DV3yJgDOK4bHTImkdA0fcBoiVk1YjqZSQVbTvhWHryCKX1/NsLKOHQieEsp1wshU2+QGVLPWJcf97vT+q2EbXshtaglk74s4AdWIWgQ0ojsSuY1fMSkOq/JsM15uBfauxjgRCJ4jx8hreEdfEphwNxa4h1TMckIwaf44ny78dnrr1EIeQCPFlSywUR7PiebpiEZp+rlKl+wra3qV278jlQcYhUPH4dS78UuL9L1z6FswDUQLWfbDrgpWOjkVI79bf+RaAw60Vk0gL2iFgkUgWwC8Y3owcl3DAMg1PWPmMP/QA0zibv4XaqYIjKUXUuJF9Ql/szgZpIIBsjCCAa6gAwIBEqKCAaUEggGhk5lB+Z5f9nhYsC/OsyU9OjUne8HkSAjJYwyKGx2VwPWd8D2QtWc+teOYY4FVrct6fW/S5MGoeRyfguyxcI2oUtQ9MSSozDfA4kylYiOKVzLFfYNP+FIlLg/QfkxDW6NblIawss6n3fEke052yZZDfoYu3wjz476OCbS9O9rrn7O6FpoJ1YjdTxOEs2bugDC89nZAqdthiquo+/mEgHTbyhl5n7RF7gyciLwQ2pflcnRRPlOmZe7POm4WHaO/uUM7mNCQIbYYQFpjYFPqJnF9x21hbJ9NcAbpapXZzdPdz+5hBRsIeSupqcjRM5/bKVClcbl0N8E68gO0ZN1UNQO8Q4dSLRqSKc1/1hy47hCXI8AB+WgpDnQl8NBBFITc8UXf/zGfMZtjtzXYaQYS0dc3C5Ko+wWKScAFg725XgvXxyjzZQJxzHWyqZ8dnt0YkjkMbDi9nv85y0J0LqZ1l3gvIlWE2xSkql4ARlqy92NJaKtNfCT2QAluFpfGnYtKThseAG4Megs9SXGGMPMrABAy22iseCoiAJC3wl9BuaWZVYa1
    
    

    It seems there's some extra stuff in the requests_kerberos line? (The HTTP endpoint is in there, b64 encoded?) Does that tell you anything useful about what might be going on?

    (Also, I did a naive search, and saw #173 - just for completeness, I did try appending send_cbt=False to the kerberos_auth line, and the issue still occurs - so I'm assuming it's not the channel-binding stuff).

  4. jborean93 commented on May 9, 2025

    @jborean93
    Contributor

    If you compare the raw tokens that were exchanged here, the one send and received by requests-kerberos is:

    # Needs pyspnego, ruamel.yaml
    # python -m spnego --format yaml --token YIIDTQYJKoZIhvcSAQICAQBuggM8MIIDOKADAgEFoQMCAQ6i...
    MessageType: SPNEGO InitialContextToken
    Data:
      thisMech: Kerberos (1.2.840.113554.1.2.2)
      innerContextToken:
        MessageType: AP-REQ (14)
        Data:
          pvno: 5
          msg-type: AP-REQ (14)
          ap-options:
            raw: 32
            flags:
            - mutual-required (32)
          ticket:
            tkt-vno: 5
            realm: REALM.COM
            sname:
              name-type: NT-SRV-HST (3)
              name-string:
              - HTTP
              - proxy1.realm.com
            enc-part:
              etype: AES128_CTS_HMAC_SHA1_96 (17)
              kvno: 1
              cipher: ...
          authenticator:
            etype: AES256_CTS_HMAC_SHA1_96 (18)
            kvno:
            cipher: ...
        RawData:  ...
    RawData: ...
    # python -m spnego --format yaml --token oRQwEqADCgEBoQsGCSqGSIb3EgECAg==
    MessageType: SPNEGO NegTokenResp
    Data:
      negState: accept-incomplete (1)
      supportedMech: Kerberos (1.2.840.113554.1.2.2)
      responseToken:
      mechListMIC:
    RawData: A1143012A0030A0101A10B06092A864886F712010202

    The one that from a working client is:

    # python -m spnego --format yaml --token ...
    MessageType: SPNEGO InitialContextToken
    Data:
      thisMech: SPNEGO (1.3.6.1.5.5.2)
      innerContextToken:
        MessageType: SPNEGO NegTokenInit
        Data:
          mechTypes:
          - Kerberos (1.2.840.113554.1.2.2)
          reqFlags:
          mechToken:
            MessageType: SPNEGO InitialContextToken
            Data:
              thisMech: Kerberos (1.2.840.113554.1.2.2)
              innerContextToken:
                MessageType: AP-REQ (14)
                Data:
                  pvno: 5
                  msg-type: AP-REQ (14)
                  ap-options:
                    raw: 0
                    flags: []
                  ticket:
                    tkt-vno: 5
                    realm: REALM.COM
                    sname:
                      name-type: NT-PRINCIPAL (1)
                      name-string:
                      - HTTP
                      - authzd-proxy-i18n.realm.com
                    enc-part:
                      etype: AES128_CTS_HMAC_SHA1_96 (17)
                      kvno: 1
                      cipher:  ...
                  authenticator:
                    etype: AES256_CTS_HMAC_SHA1_96 (18)
                    kvno: 1
                    cipher:  ...
                RawData:  ...
            RawData:  ...
          mechListMIC:
        RawData: ...
    RawData:  ....

    We can see that the server rejected the Kerberos token from requests-kerberos but it doesn't really indicate why/what went wrong. The only real way to determine what went wrong would be to look at the logs on the server side to see if it gives any indications of what went wrong.

    There are some differences through:

    • requests-kerberos just sends the raw Kerberos token whereas the other tool wraps the Kerberos token inside a SPNEGO payload
      • The response you get back from the server is a SPNEGO response and would indicate why the GSSAPI library is failing to parse that token
    • The SPN on the requests-kerberos token is for the SPN HTTP/proxy1.realm.com whereas the other tool is HTTP/authzd-proxy-i18n.realm.com
      • Maybe the other tool is canonicalising the hostname or doing some other work to resolve it, requests-kerberos just uses the hostname from the request
      • The hostname_override kwarg can be used to override this behaviour and provide a different hostname in the SPN if you wish
      • The local krb5.conf also has a few options around hostname canonicalisation but the options and what they do depend on the platform and version you are running on

    The first difference can be solved by using the requests-gssapi library which has a similar API to this one but uses SPNEGO/Negotiate packets rather than just pure Kerberos. This may solve the problem if that's what the server did not like but if it was because of the incorrect SPN being used then you will have to look at your krb5.conf or provide a custom hostname override so it uses the correct one rather than the hostname from the request.

  5. victorhooi commented on May 9, 2025

    @victorhooi
    Author

    Aha - I got it working! Still one very small question about usability though - as I need to mutate the hostname_override, and I'm not sure if that's possible?

    Anyway - my notes on what worked here. There are two types of HTTP requests I need to make here - a GET to one endpoint, and a PUT to a different endpoint. They're both meant to use Kerberos auth.

    For the GET requests - it appears to be the SPNEGO wrapping you mentioned. Replacing:

    from requests_kerberos import HTTPKerberosAuth
    

    with:

    from requests_gssapi import HTTPKerberosAuth
    

    However, for the POST query - using requests_gssapi.HTTPKerberosAuth still fails with the below error:

    DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): proxy-service-i18n.foo-row.org:80
    DEBUG:urllib3.connectionpool:http://proxy-service-i18n.foo-row.org:80 "POST /api/v1/gss/demand HTTP/1.1" 401 15
    DEBUG:requests_gssapi.gssapi_:handle_401(): Handling: 401
    ERROR:requests_gssapi.gssapi_:generate_request_header(): stepping context failed:
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_gssapi/gssapi_.py", line 163, in generate_request_header
        gss_response = self.context[host].step(_negotiate_value(response))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 165, in check_last_err
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 584, in step
        return self._initiator_step(token=token)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
        res = rsec_contexts.init_sec_context(self._target_name, self._creds,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
    gssapi.raw.exceptions.BadMechanismError: Major (65536):  An unsupported mechanism was requested, Minor (0): unknown mech-code 0 for mech unknown
    ERROR:requests_gssapi.gssapi_:Major (65536):  An unsupported mechanism was requested, Minor (0): unknown mech-code 0 for mech unknown
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_gssapi/gssapi_.py", line 163, in generate_request_header
        gss_response = self.context[host].step(_negotiate_value(response))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 165, in check_last_err
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 584, in step
        return self._initiator_step(token=token)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
        res = rsec_contexts.init_sec_context(self._target_name, self._creds,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
    gssapi.raw.exceptions.BadMechanismError: Major (65536):  An unsupported mechanism was requested, Minor (0): unknown mech-code 0 for mech unknown
    DEBUG:requests_gssapi.gssapi_:handle_401(): returning <Response [401]>
    DEBUG:requests_gssapi.gssapi_:handle_response(): returning <Response [401]>
    DEBUG:requests_gssapi.gssapi_:handle_response() has seen 0 401 responses
    DEBUG:requests_gssapi.gssapi_:handle_401(): Handling: 401
    ERROR:requests_gssapi.gssapi_:generate_request_header(): stepping context failed:
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_gssapi/gssapi_.py", line 163, in generate_request_header
        gss_response = self.context[host].step(_negotiate_value(response))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 165, in check_last_err
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 584, in step
        return self._initiator_step(token=token)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
        res = rsec_contexts.init_sec_context(self._target_name, self._creds,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
    gssapi.raw.exceptions.BadMechanismError: Major (65536):  An unsupported mechanism was requested, Minor (0): unknown mech-code 0 for mech unknown
    ERROR:requests_gssapi.gssapi_:Major (65536):  An unsupported mechanism was requested, Minor (0): unknown mech-code 0 for mech unknown
    Traceback (most recent call last):
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/requests_gssapi/gssapi_.py", line 163, in generate_request_header
        gss_response = self.context[host].step(_negotiate_value(response))
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 165, in check_last_err
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/decorator.py", line 235, in fun
        return caller(func, *(extras + args), **kw)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/_utils.py", line 131, in catch_and_return_token
        return func(self, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 584, in step
        return self._initiator_step(token=token)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/Users/foobar/code/foobar/api_menangerie/.venv/lib/python3.12/site-packages/gssapi/sec_contexts.py", line 606, in _initiator_step
        res = rsec_contexts.init_sec_context(self._target_name, self._creds,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "gssapi/raw/sec_contexts.pyx", line 188, in gssapi.raw.sec_contexts.init_sec_context
    gssapi.raw.exceptions.BadMechanismError: Major (65536):  An unsupported mechanism was requested, Minor (0): unknown mech-code 0 for mech unknown
    DEBUG:requests_gssapi.gssapi_:handle_401(): returning <Response [401]>
    DEBUG:requests_gssapi.gssapi_:handle_response(): returning <Response [401]>
    DEBUG:requests_gssapi.gssapi_:handle_response() has seen 1 401 responses
    DEBUG:requests_gssapi.gssapi_:handle_response(): returning 401 <Response [401]>
    Unauthorised.
    

    Here are the sample HTTP Authorization headers using the official client, for both types of queries.

    HTTP GET request:

    Negotiate YIICcQYGKwYBBQUCoIICZTCCAmGgDTALBgkqhkiG9xIBAgKiggJOBIICSmCCAkYGCSqGSIb3EgECAgEAboICNTCCAjGgAwIBBaEDAgEOogcDBQAAAAAAo4IBa2GCAWcwggFjoAMCAQWhDxsNQllURURBTkNFLkNPTaIrMCmgAwIBAaEiMCAbBEhUVFAbGHByb3h5MS5vcnRocnVzLmJ5dGVkLm9yZ6OCARwwggEYoAMCARGhAwIBAaKCAQoEggEGezDaDdq86p3JS30LZzd+rb9Xxx+aAH1U+LgHmPOSiCb4qyeIixbEKkJR8w2fyiCrGtI8Yz4BUIci1BY944EGWeN3ogECbJVre/V5KSIufj4Gwqu3JO70WJ7Rrvj0ULno8EdnD1RwlkBcNuTukyT0pDKCV56qfhjSkSIHTWJzXkUt8hbeHm8HmCp/Ti7QHtRU7zcw5dad0/5u0kfqnFV3TLNRbCu93Qrmc59u3cqJveQd39hmfcr5QNpSKuJhrTZIlfTCC9wIiRRPBZUdUTkc1/VAO/ONNbt7qc5nSw6uOQd2FRixzrj5vAvcyTLm8Kibh+IpHMPRt1kaGtbI6hyKk5T1FumzNKSBrDCBqaADAgESoQMCAQGigZwEgZm7Vq1gbSWD/26op7HS/DhXoIxS/BOPjoUper9VP/EVYc4rrQGEeU+fkFYypSHcjVrKR/Vf0JJJ45PPeH0bPxO0MEF9UAIG6tbn+LqgaJ/mv0MKvH7zfrCobtOo3QiA5YAphUI0rU0cU23iHXAXhB7mH3r7ZDa95Hx4msRVUfVGJ80g41Z0NZinntZ2Ynle8h7F3iXPVmUct/w=
    

    HTTP POST request:

    Negotiate YIICfwYGKwYBBQUCoIICczCCAm+gDTALBgkqhkiG9xIBAgKiggJcBIICWGCCAlQGCSqGSIb3EgECAgEAboICQzCCAj+gAwIBBaEDAgEOogcDBQAAAAAAo4IBeWGCAXUwggFxoAMCAQWhDxsNQllURURBTkNFLkNPTaI5MDegAwIBAaEwMC4bBEhUVFAbJmF1dGh6ZC1wcm94eS1pMThuLm9ydGhydXMtdXMuYnl0ZWQub3Jno4IBHDCCARigAwIBEaEDAgEBooIBCgSCAQYqaO22FXvjpNoVarvFBags0EdKEiNs/9mRd/080e5ykO31gPbFdhorccu+P/3cCZo+u/5FcMHvmL8z78OUDEi4dU+pRxpEwtpR9Q5yaYbQA8/lurTWyktMeJ9C+oIszMiBQGS/WSyg0TPAD7dZJx0AGt6iITQCRsk9HzAq3g0UGC29iTZ1CKAICG6AAetZTgqMXFStTRoBY1hG3VtLO17SWTNoxzett9GjVkcgwrsnVNS5GHRDLDdVnYDVGypNXvL9T7pqf9k+i/8kDu8XHOGdNxntCLjjgHxegbkTHt9W7m1PxRs9qHN0whKesgNNOc3LUUkJdOZvTgPsIDV45LmYJDorNL1VpIGsMIGpoAMCARKhAwIBAaKBnASBmUpqpyLpc9WK3Rbq41az9G2QTA3+B+Td42pxzw8CMdurHh5UwRb+1DkfKzX6sXZfcKfjRqoUpy3i6oK6AAausw/P18SpYArJ1RZL1/fKBRdBVgY8Mx2VsXBVyPXSjLO6LX1pqAXjqXz4wY2D+tYFOfD6yjtZj7afEnx/3q1nm5xtUFFtwSaxFRCvSDYkSh1rScd6mLXvK8hyfw==
    

    I did try the python3 -m spnego --format yaml --token trick you showed in the last post 😃, and did a quick diff on the output - but I couldn't spot any obvious differences, aside from the sname -> name-string.

    However, I found out that using a hostname_override combined with requests_gssapi makes the POST request to the other endpoint work 🤷.

    Previously I was using a single kerberos_auth = HTTPKerberosAuth(...) object, to make all the requests calls - is that how I should be doing it?

    Also, I'm assuming you can't set, then unset 'hostname_override`, right? Or is there some way to achieve that?

  6. jborean93 commented on May 12, 2025

    @jborean93
    Contributor

    as I need to mutate the hostname_override, and I'm not sure if that's possible?

    The only way to achieve is by using the hostname_override kwarg when building the HTTPKerberoAuth object. If you are using this against multiple hosts then you'll have to provide one of these objects per host.

    An unsupported mechanism was requested

    That would tell me the local GSSAPI library doesn't support the mechanism requested. This is more a question on requests-gssapi but it does have a kwarg to specify a custom mech. By default it uses SPNEGO so you may want to change it to just Kerberos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions