[jcifs] Re: SPNEGO with JGSS

eglass1 at comcast.net eglass1 at comcast.net
Fri May 7 16:53:01 GMT 2004


> > 
> > I don't know if anyone has posted this before but it looks interesting:
> > 
> > http://bofriis.dk/portalprotect/SPNEGO%20authentication%20using%20JGSS.pdf
> > 
> > Mike
> > 
> > 
> 
> The whole Website looks very interesting!
> http://bofriis.dk/
> 
> e.g. the Tomcat SPNEGO authenticator
> http://bofriis.dk/spnego/tomcat_spnego.html
> 

Yes, this is something I've picked up and put down 3 or 4 times over the past
year.  See the attached SPNEGO token implementations (using the BouncyCastle
ASN.1 implementation), and the previous stuff here:

http://lists.samba.org/archive/jcifs/2003-May/002127.html

Implementing Kerberos authentication for HTTP via SPNEGO isn't terribly
difficult; someone with a decent working knowledge of the framework could
put something together fairly easily (especially since the Kerberos
implementation is provided out-of-box in JDK 1.4).  You really just need
to slap some ASN.1 parsing in to extract the Kerberos tokens, then send
them on using the process described in the paper cited previously.

What is a bit more difficult (still not too bad) is doing the actual
"negotiation" part of SPNEGO (see the TokenFactory stuff from the link
above; kind of obtuse, but it works).  To work effectively and thoroughly,
the underlying authentication mechanism needs to be negotiated between the
client and server.  There are a few scenarios:


1) Raw NTLM -- the client sends the "Negotiate" auth header, but instead
of a SPNEGO token it just sends the NTLM type1, type 2 etc. messages.
The server effectively reverts to NTLM authentication.  The only difference
between this scenario and the NTLM authentication we currently do is the
"Negotiate" header.

2) SPNEGO w/NTLM -- SPNEGO is used to negotiate an underlying authentication
mechanism; one such mechanism is NTLM.  Here the NTLM tokens are wrapped
in SPNEGO tokens.

3) SPNEGO w/Kerberos -- This is the "common" mechanism (which is what the
article is describing); SPNEGO tokens wrap Kerberos tokens.


So while you can get HTTP SPNEGO/Kerberos authentication going fairly easily,
unless all of the above scenarios are supported you'll end up "locking out"
some downlevel clients.

The ideal way to implement all of this would be as a set of GSS-API providers
(which is what I believe the Wedgetail JCSI product does).  This is a general
framework for token-based authentication, where client and server pass opaque
tokens back and forth until the underlying mechanism indicates the handshake
is complete.  The API very closely mirrors Microsoft's SSPI (which provides
the same functionality, and is what their authentication framework is based
on).

HTTP authentication using GSS-API (on the client side) looks like this:

    byte[] inToken = new byte[0];
    while (!context.isEstablished()) {
        byte[] outToken = context.initSecContext(inToken, 0,
                inToken.length);
        if (outToken != null) {
            // Base-64 encode outToken and send it to the
            // server in the "Authorization" header
            sendAuthHeader(base64Encode(outToken));
        }
        if (!context.isEstablished()) {
            // read token from the server's "WWW-Authenticate"
            // header and Base-64 decode it.
            // if the status is a 401, we will need to
            // send another token
            inToken = base64Decode(readAuthHeader());
        }
    }

The tokens are simply transported over the WWW-Authenticate and Authorization
HTTP headers.

>From the SMB perspective GSS-API/SSPI is, effectively, extended security:

    byte[] inToken = new byte[0];
    while (!context.isEstablished()) {
        byte[] outToken = context.initSecContext(inToken, 0,
                inToken.length);
        if (outToken != null) {
            // stick outToken into session setup security blob
            // field and send to server
            sendSessionSetup(outToken);
        }
        if (!context.isEstablished()) {
            // read security blob from session setup response.
            // if the status is "more processing required"
            // we will need to send another token
            inToken = readSessionSetupResponse();
        }
    }

i.e., the tokens from the initSecContext calls are passed to the server
via the security blob field of the session setup; the server's tokens
(generated from acceptSecContext) are passed back in the session setup
response.  The tokens will be one of the above -- raw NTLM, SPNEGO/NTLM,
or SPNEGO/Kerberos.


Eric
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/octet-stream
Size: 1967 bytes
Desc: not available
Url : http://lists.samba.org/archive/jcifs/attachments/20040507/74cce7bd/attachment.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/octet-stream
Size: 2803 bytes
Desc: not available
Url : http://lists.samba.org/archive/jcifs/attachments/20040507/74cce7bd/attachment-0001.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/octet-stream
Size: 1726 bytes
Desc: not available
Url : http://lists.samba.org/archive/jcifs/attachments/20040507/74cce7bd/attachment-0002.obj


More information about the jcifs mailing list