Re: "negotiate" auth with fallback to other schemes

From: Henrik Nordström <henrik_at_henriknordstrom.net>
Date: Tue, 23 Feb 2010 19:49:37 +0100

tis 2010-02-23 klockan 14:44 +0100 skrev Livio B:

> The way this works is that the server first returns a 407 page with
> e.g. 2 headers: Authenticate: Negotiate and Authenticate: Basic; then
> the browser tries with its kerberos ticket or current user's ntlm
> credentials (without user interaction); if those are accepted then
> fine, otherwise the server returns a new 407 page again with just the
> Authenticate: Basic header and not the Negotiate one (this behavior is
> supported e.g. in the java spnego sourceforge project and the apache
> spnego module).

Can do.

> Unfortunately this is not possible with squid because, when Negotiate
> fails, squid returns a new 407 page that includes the "Authenticate:
> Negotiate" header again. Note that when using the squid_kerb_auth
> helper, this causes the browser (in the case that the client has no
> valid kerberos ticket) to repeatedly prompt the user for NTLM
> credentials that will never get accepted by the helper anyway (and
> never switches to Basic).

Correct, as the browser supports Kerberos and NTLM and prefers using
those. Both supports prompting the user for credentials just as basic
does.

> So the idea is to extend the negotiate helper protocol so that the
> helper can specify that its auth mechanism should no longer be offered
> to the client (this might be useful for other mechanisms too). This
> way it would be up to the helper to decide if its scheme should be
> reiterated or not.

I would say this fits better as an auth_param setting. Both Negotiate
and NTLM protocols has a clear "Authentication has failed due to invalid
credentials" message (NA ....).

Why do the helper need to decide if the user should be prompted again?
In which cases should the user get prompted again for Negotiate or NTLM
after incorrect authentication?

> My main doubt is where to keep the information about "disabled"
> schemes. In my current test I keep a list of "still active" auth
> schemes in the HttpRequest object. However the problem with this is
> that the httprequest object is (seems to be) freed as soon as the
> connection is closed. Therefore this works only for the first auth
> reiteration, that is, this is what can happen:

Simplest is to add a per-connection flag indicating that connection
oriented auth (NTLM / Negotiate) should not be used for this connection.

I don't think there is need for more advanced fallback than "only try
Basic is connection oriented auth fails". I don't see any reasonable use
cases where one would want fallback on NTLM is Negotiate fails as the
two is so tightly related.

> One possible solution could be to not force a connection-close after a
> failed authentication (it shouldn't be necessary, should it?).

That's absolutely necessary for this to work out. If the connetion is
dropped then there is no place where to keep track of the state.

Doing it on the IP level is not right, as there may be many users
sharing the same IP (NAT:ed, using an internal proxy, or running on
terminal server or other multi-user server).

> But
> maybe there are also other objects that are more suitable to keep this
> information and that persists at least until authentication is fully
> completed? I'd be happy to get your advice on this point and the whole
> idea.

HTTP auth is done per message.

NTLM & Negotiate is not actually HTTP auth and is done per TCP
connection, while looking seemingly like HTTP auth in the initial
steps..

Regards
Henrik
Received on Tue Feb 23 2010 - 18:49:43 MST

This archive was generated by hypermail 2.2.0 : Wed Feb 24 2010 - 12:00:10 MST