"negotiate" auth with fallback to other schemes

From: Livio B <lbsqdd_at_gmail.com>
Date: Tue, 23 Feb 2010 14:44:19 +0100

Hello,

I'd like to slightly improve the negotiate authentication mechanism.

The motivation is that, by using the Negotiate (and probably also
NTLM) auth mechanism, it should be possible to support SSO-only
authentication, in the sense that either the client authenticates
transparently (without prompting the user), or the mechanism is
dropped entirely and the user is either not authenticated or
authenticated in a different way.
This is useful for example if you want to transparently authenticate
clients in a windows domain and reject others, or maybe either
authenticate clients via kerberos but, if the client doesn't have a
valid kerberos ticket, then switch to a different mechanism (such as
"basic" against an ldap server).

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).
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).

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 have written a proof-of-concept patch that keeps the protocol as is
but, for the h->s messages (which are of the form "XX blablabla"), it
also recognizes the variant "XX.blablabla" (that is with a dot instead
of a blank after the 2-letters message ID) with the meaning: "final,
do not offer this mechanism again". This can make sense both for BH/NA
(auth failed) messages and for AF messages (in case that auth was
successful but the user is not authorized to get the requested page).
It is probably useless in TT messages.

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:
- client requests a page
- squid requires auth and proposes e.g. negotiate and basic
- client tries negotiate with invalid credentials (e.g. with ntlm
instead of kerberos)
- squid doesn't accept the credentials, eventually marks negotiate as
disabled (if the helper says so) and proposes only basic, then closes
the connection and drops the httprequest object
- client tries basic with invalid credentials
- squid rejects again but at this point doesn't "remember" that
negotiate is disabled, so proposes negotiate and basic again
While this works anyway (it just causes the browser to retry with SSO
another time, before prompting the user again for other Basic
credentials), it doesn't seem right.

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

Thanks
Livio
Received on Tue Feb 23 2010 - 13:45:59 MST

This archive was generated by hypermail 2.2.0 : Tue Feb 23 2010 - 12:00:09 MST