Kerberos Authentication question(s)

Benjamin Kaduk kaduk at MIT.EDU
Thu Jun 25 12:39:41 EDT 2015


Just a couple additions and corrections (inline).

On Wed, 24 Jun 2015, Michael B Allen wrote:

> On Wed, Jun 24, 2015 at 2:07 PM, Albert C. Baker III <albert at voltage.com> wrote:
> > I am using the Java class org.apache.hadoop.security.
> > authentication.server.AuthenticationFilter from Apache
> > Hadoop 2.5.0 as a filter in front of a Tomcat 6 Servlet we
> > wish to add Kerberos authentication to.

Michael has basically made this point at the end of his message, but just
to drive it home: the HTTP Negotiate authentication you are using is the
SPNEGO mechanism for the GSS-API protocol.  Since the GSS-API is the
Generic Security Service Application Programming Interface (emphasis on
Generic), it supports using security mechanisms other than Kerberos, even
though Kerberos is what you want to use with it (and what most people use
with it).  Your goal (described below) of constructing a token by hand
using the server's private key is inherently plowing through several
layers of abstraction, and because the GSS-API is generic, not specific to
Kerberos, there are not interfaces which facilitate such abstraction
violations.

> gotten better over the years). Note that the reason the Windows SSPI
> is used by Java is largely because there is otherwise no way to insert
> credentials into the Windows credential cache. It actually used to be
> possible but at some point early on MS decided this was probably not a
> good idea and so now Java and MIT or Heimdal or whoever cannot insert
> creds into the Windows credential cache. They have to just use the

This is simply not true -- both MIT KfW and Heimdal for Windows can insert
Kerberos credentials into the Windows LSA credential cache.

> >   SomeTokenType token = new SomeTokenType();
> >   <code to set token parameters>
> >
> >   // my understanding of Kerberos is that the only cyphertext key
> >   // needed on this token
> >   // is one of the server principal's keys from the Keytab file
> >   // (which does contain ~5
> >   // keys of different sizes and types, I've checked)
> >   EncryptedTokenType etoken = <encrypt token with a key from keys>
> >   byte[] array = etoken.getBytes();
>
> First, note that the "token" in the Authorization / WWW-Authenticate
> headers in HTTP are not quite the same as the "token" as defined in
> the Kerberos protocol documentation. Technically, the HTTP "token" is
> the Base64 encoded product of the InitializeSecurityContext function
> of the Microsoft Windows SSPI of which there are several but could be
> Kerberos or NTLM but in practice almost always SPNEGO which is a
> little binary wrapper used to NEGOtiate Keberos or NTLMSSP where
> NTLMSSP is a little binary wrapper around NTLM.

Yes (though I don't think that the output of InitializeSecurityContext is
the normative reference in the RFCs -- it's wire-compatible with the
corresponding GSS-API tokens, which are used in the SPNEGO and
HTTP-Negotiate specs).

> Lost yet? Anyway, with
> respect to Windows HTTP clients (including Firefox and Chrome running
> on Windows which just tap into the Windows SSPI), the HTTP "token" is
> almost certainly an SPNEGO token. However, if you're just trying to
> initiate authentication (meaning you're the client), you can
> *probably* skip SPNEGO and feed the server a raw Kerberos token. At

Right -- this token is passed as input to gss_accept_sec_context() (or the
Windows equivalent), and the acceptor is willing to handle whatever
mechanisms the implementation supports, which will include both SPNEGO and
Kerberos, here.  (It is possible for the acceptor to construct a
credential that is limited to only certain mechanisms, but I believe this
to be rare.)

> least Windows servers like IIS should detect this and handle it
> correctly. And Apache's mod_auth_kerb would almost certainly handle it
> correctly as well.
>
> > So, questions here:
> >   1) What is the Java Class that embodies the Kerberos Auth Token sent
> >      in "Authorization Negotiate"?
>
> Again I am not familiar with your "token" code but fortunately, even
> though the Authorization: Negotiate ... token is an Internet
> Explorer-ism, it's SPNEGO payload is largely compatible with the

Huh?  HTTP-Negotiate is published as RFC 4559 and is supported by all
major browsers.  The token formats described therein are explicitly the
SPNEGO GSS-API token formats; there's no need to hedge with "largely".

> Kerberos token and more generally the GSSAPI token where GSSAPI is the
> RFC definition of this type of authentication which is meaningful
> because JGSS is the Java implementation of this and this is a run-on
> sentence.
>
> So with respect to actually coding a Java HTTP client to do Kerberos,
> something would ultimately need to call GSSManager.createContext with
> the Kerberos OID and then GSSContext.initSecContext and then the
> result of looping over that consumes and emits a "token" (which
> *should* then be wrapped in the SPNEGO business) and Base64 encoded /
> decoded. Maybe the "Hadoop" library is doing that for you. I'm not
> familiar with it. Personally I would be very skeptical of libraries
> that do this type of stuff. HTTP authentication is actually a lot
> harder than it looks because HTTP is stateless and so technically
> trying to do authentication (which is inherently stateful) over a
> stateless protocol is something of an oxymoron. So test your code
> carefully using all of the possible environmental parameters like
> different servers or whatever.

HTTP-Negotiate is even worse, in that it ties things to the underlying
TCP/TLS connection, which is a clear violation of the spec.  There are
mostly-reasonable ways to do HTTP authentication with strong crypto
(imagine an RPC-like system which gets a token that is used to
authenticate subsequent requests, with explicit parameters in the RPC to
preserve server state across iterations in the authentication loop), but
this one is not it.

> >   2) What fields of that auth token have to be set to what values?
> >   3) What is the encryption algorithm used to encrypt the auth token
> >      against the keytab key?
> >   4) What is the best keytab key to use?
> >   5) What is the mechanism for byte-serializing the auth token, once
> >      encrypted?
>
> As described above, fortunately you probably don't have to worry about
> the actual content of the token as it is largely handled by GSSAPI /
> JGSS.

Right.  (That is, I do not expect those data structures to be exposed to
library callers.)

-Ben


More information about the Kerberos mailing list