httphttp-authenticationhttp-negotiate

How does the Negotiate HTTP authentication mechanism establish a session?


As described in RFC 4559, the Negotiate mechanism may take several requests to complete a GSSAPI context. I cannot understand from the RFC what mechanism is used to associate those requests with one another, however. To take the example described in section 5 of the the RFC:

1:
  C: GET dir/index.html

2:
  S: HTTP/1.1 401 Unauthorized
  S: WWW-Authenticate: Negotiate

3:
  C: GET dir/index.html
  C: Authorization: Negotiate a87421000492aa874209af8bc028

4:
  S: HTTP/1.1 401 Unauthorized
  S: WWW-Authenticate: Negotiate 749efa7b23409c20b92356

5:
  C: GET dir/index.html
  C: Authorization: Negotiate 89a8742aa8729a8b028

This is clear to me up until step 5. Assuming there are potentially many clients doing authentication at the same time, how does server know that the Authorization header in step 5 is the response to the data from step 4? I can't see any mention of session cookies or anything, and while I'm not an expert on GSSAPI, I don't think there's anything inherent in the GSSAPI data that can be used to associate it with an authentication session.

So what's the deal? :)


Solution

  • State is maintained using the TCP connection. RFC-4559 doesn't spell this out directly, likely because it would make the author feel dirty. But they elude as much in section 6 when discussing "Session-Based-Authentication" when proxies are involved. This requirement is also "called-out" in the last paragraph of RFC-7230 section 2.3 when discussing how HTTP is supposed to be a stateless protocol:

    Some non-standard HTTP extensions (e.g., [RFC4559]) have been known to violate this requirement, resulting in security and interoperability problems

    There is even more ambiguity with another requirement in the last paragraph in Section 6:

    When using the SPNEGO HTTP authentication facility with client-supplied data such as PUT and POST, the authentication should be complete between the client and server before sending the user data. The return status from the gss_init_security_context will indicate that the security context is complete. At this point, the data can be sent to the server.

    So the server should remember the authentication state after the context is successfully completed (and sent the client the 200 with the last token), to let-in one last request containing the actual payload?

    Your confusion is justified.