What should I use `WWW-Authenticate: Negotiate <value>` for, when authenticating using Kerberos?

411 views Asked by At

I have a web server than returns a WWW-Authenticate: Negotiate HTTP header (no <value>), which indicates the client should authenticate using Kerberos.

Then the client generates a Kerberos token as follows (the input token is empty):

gss_init_sec_context(
                    &minor_status, GSS_C_NO_CREDENTIAL, (gss_ctx_id_t*)context, (gss_name_t)name, GSS_KRB5_MECHANISM,
                    request_flags, 0, GSS_C_NO_CHANNEL_BINDINGS, (gss_buffer_desc*)input_token_x, nullptr,
                    (gss_buffer_desc*)output_token, &return_flags, nullptr);

This token can only be used for a single request (why?) for which the server responds with a WWW-Authenticate: Negotiate <value> HTTP header, like:

WWW-Authenticate: Negotiate YIGZBgkqhkiG9xIBAgICAG+BiTCBhqADAgEFoQMCAQ+iejB4oAMCARKicQRv3w2k6UrZ+MQ2wnUaWFxGjiWXi/QHrcdcjlklMW7uCgYUsaLqwO6ihBIxjfSSSHxmMm6JMwbf/0xrN8gMq5D9By9/5YKIOzQWKjwm73CfkrvMAq+Ns0StFfXxkx3rFm2u0OBpuaB77TubvLsMap45

Now what should this <value> be utilized for?

Should I run gss_init_sec_context() with an empty input token before every web request, similar to how it's done in requests-kerberos?

It seems wrong thus... I would like to obtain a long-lived token. How is the <value> normally utilized?

1

There are 1 answers

29
n. m. could be an AI On BEST ANSWER

You generate the initial token for an Authorization: Negotiate request by calling gss_init_sec_context() with no input token.

If the server returns a 401 with WWW-Authenticate: Negotiate <value>, it means the negotiation has not finished yet. You call gss_init_sec_context() again, this time passing the value as the input token parameter (after decoding). You send the resulting token with another Authorization: Negotiate request. You do it until you either get WWW-Authenticate: Negotiate with no data attached (meaning the negotiation has failed), or some other response, normally 200 but may be anything else like 301 (meaning the authorization has succeeded).

Some servers may be configured to require authentication with every request or once per connection. If the latter, the server will not send WWW-Authenticate with subsequent requests and you don't need to send any Authorization. The server will send Persistent-Auth: true if so. At any rate you cannot reuse the negotiation token. You either issue a new token for every request, or do not send any tokens after the initial one if Persistent-Auth is set to true.

You don't have to wait for WWW-Authenticate: Negotiate to generate a token. If you know that the server uses this protocol, just send Authorization: Negotiate <token> right away.

Now you may get another WWW-Authenticate: Negotiate with a token with a 200 response (or I presume other responses indicating success). This token is the server's mutual authentication token. If you get one, you should call gss_init_sec_context() with it yet another time. If gss_init_sec_context() returns a success, you are all set. Otherwise it means that the client could not authenticate the server (maybe the server was not set up correctly, or someone is trying to impersonate it).

References:

  1. RFC 4559
  2. Persistent-Auth