The Oracle GSSAPI Java examples, and various SPNEGO / GSSAPI IETF RFCs indicate that both the GSS initiator (client) and acceptor (server) should have a loop to establish a security context, and that the client may need to make multiple passes with GSS tokens before the security context is established.
Oracle GSSAPI example: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/tutorials/BasicClientServer.html
Structure of the Generic Security Service (GSS) Negotiation Loop: https://www.rfc-editor.org/rfc/rfc7546
SPNEGO-based Kerberos and NTLM HTTP Authentication in Microsoft Windows: https://www.rfc-editor.org/rfc/rfc4559
For instance RFC4559 gives this example:
Pass 1: Fails because request does not have a token:
C: GET dir/index.html
S: HTTP/1.1 401 Unauthorized
S: WWW-Authenticate: Negotiate
Pass 2: Fails, but request has a token
C: GET dir/index.html
C: Authorization: Negotiate a87421000492aa874209af8bc028
S: HTTP/1.1 401 Unauthorized
S: WWW-Authenticate: Negotiate 749efa7b23409c20b92356
Pass 3: Succeeds
C: GET dir/index.html
C: Authorization: Negotiate 89a8742aa8729a8b028
S: HTTP/1.1 200 Success
S: WWW-Authenticate: Negotiate ade0234568a4209af8bc0280289eca
Here the security context is established and thus the request is authenticated on the third pass. i.e. on the second pass from the client (C) to server (S) with a token.
Question 1: Why might multiple passes from initiator to acceptor with tokens be required before the security context is successfully established? Why might pass 2 above fail, but pass 3 succeed? Does something change on either the initiator or the acceptor between these 2 passes?
Question 2: My instinct is that both the initiator and acceptor loops should have protection against endless looping. For instance the initiator could abort if the context is not established by x attempts. Are there any rules-of-thumb / metrics on the number of passes that might reasonably be expected to establish the security context? e.g. if the security context has not been established by the 5th pass --> abort.
Question 3: In the Oracle GSSAPI examples the client and server communicate over sockets. The server builds a GSSContext object which is dedicated to a single client, is kept until the server closes, and is thus available for multiple passes to establish the security context.
But how might this work for a Http RESTful WebServer with multiple clients? My assumption is that:
a) each pass of a request to establish a security context should be made to the same GSSContext object (and not against a new GSSContext instance).
b) the Http server should establish a new GSSContext instance for each new client request. (i.e. a GSSContext object should not be shared / reused across multiple clients / requests).
If my assumptions are correct the server must distinguish between:
i) a following pass for an existing request for which the security context has not yet been established. --> an existing GSSContext object and loop should be used.
ii) the first pass of a totally new request (either from the same or from a different client). --> a new GSSContext object and loop should be used.
Using Negotiate
as the example protocol, it's useful to consider how it operates.
This requires up to three roundtrips and may fail or complete after one. Other protocols may choose to do whatever they want.
You will probably want to track the number of roundtrips and kill it after a arbitrarily high number. The resources required aren't that high, but under load it can exhaust the system.