[jcifs] Kerberos over HTTP

Eric eglass1 at attbi.com
Tue Jan 21 00:19:30 EST 2003


Eric wrote:
> Christopher R. Hertel wrote:
>  > I assume folks are aware of this draft:
>  >
>  > http://meta.cesnet.cz/software/heimdal/draft-brezak-spnego-http-04.txt
>  >
>  > Would be interesting to extend the jCIFS tools to do Kerberos.  ;)
>  >
> 
> I actually looked at this awhile back; Java 1.4 provides the GSSAPI
> framework in the org.ietf.jgss package.  The authentication protocol
> presented in the draft, if I remember correctly, simply encodes the 
> token generated by GSSContext.initSecContext() in Base64 and sends that 
> to the client; the client produces a reply in similar form, and the 
> server Base64-decodes that and applies it as the argument to 
> GSSContext.acceptSecContext().  This sequence continues until 
> GSSContext.isEstablished() returns true (in which case the session has 
> been established).
> 
> 

I actually had the above a bit mixed up -- the server sends 
"WWW-Authenticate Negotiate", and the CLIENT sends the initSecContext() 
output -- the server just applies acceptSecContext() and sending until 
isEstablished() returns true.

Attached is what I had; I just gave up when I got "Unsupported 
Mechanism" errors and realized there was actually a significant effort 
involved ;).  Assuming my interpretation is correct (a big leap of 
faith) this should work with an installed SPNEGO mechanism provider.


Eric



-------------- next part --------------
package jcifs.http;

import java.io.IOException;

import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import jcifs.util.Base64;

public class GSSAuthFilter implements Filter {

    static {
        // example for testing
        System.setProperty("java.security.krb5.realm", "TEST.COM");
        System.setProperty("java.security.krb5.kdc", "TEST.TEST.COM:88");
    }

    public void init(FilterConfig config) throws ServletException { }

    public void destroy() { }

    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        HttpSession session = request.getSession();
        synchronized (session) {
            try {
                GSSContext context = (GSSContext) session.getAttribute(
                        "jcifs.http.GSSContext");
                if (context == null) {
                    context = GSSManager.getInstance().createContext(
                            (GSSCredential) null);
                    session.setAttribute("jcifs.http.GSSContext", context);
                }
                if (context.isEstablished()) {
                    chain.doFilter(request, response);
                    return;
                }
                String authorization = request.getHeader("Authorization");
System.out.println(authorization);
                int index = -1;
                if (authorization == null ||
                        (index = authorization.indexOf(' ')) == -1 ||
                                !authorization.substring(0, index).equals(
                                        "Negotiate")) {
                    response.reset();
                    response.setHeader("WWW-Authenticate", "Negotiate");
                    response.setContentLength(0);
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    response.flushBuffer();
                    return;
                }
                byte[] token = Base64.decode(authorization.substring(index +
                        1));
                token = context.acceptSecContext(token, 0, token.length);
                boolean established = context.isEstablished();
                if (!established) response.reset();
                if (token != null) {
                    response.setHeader("WWW-Authenticate", "Negotiate " +
                            Base64.encodeBytes(token));
                }
                if (!established) {
                    response.setContentLength(0);
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    response.flushBuffer();
                }
            } catch (GSSException ex) {
                System.out.println("Message is " + ex.getMessage());
                System.out.println("Major code is " + ex.getMajor());
                System.out.println("Major String is " + ex.getMajorString());
                System.out.println("Minor code is " + ex.getMinor());
                System.out.println("Minor String is " + ex.getMinorString());
                ex.printStackTrace();
                throw new ServletException(ex);
            }
        }
    }

}


More information about the jcifs mailing list