alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (spnegoReadme)

This example Java source code file (spnegoReadme) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

authenticator, basic, http, java, kdc, kerberos, negotiate, proxy_realm, spnego, tab_path, the, this, web, www_realm

The spnegoReadme Java example source code

//
// weijun.wang@sun.com

HTTP SPNEGO
===========

JPlan 116: SPNEGO HTTP authentication
    http://jplan.sfbay/feature/116)
RFE 6260531: SPNEGO HTTP authentication
    http://monaco.sfbay/detail.jsf?cr=6260531)
CCC 6244039: more HTTP authentication schemes to support in Java
    http://ccc.sfbay/6244039


What's HTTP SPNEGO
==================

HTTP SPNEGO supports the Negotiate authentication scheme in an HTTP 
communication. There are 2 types of authentication here:

1. Web Authentication. The Web Server responses with
       HTTP/1.1 401 Unauthorized
       WWW-Authenticate: Negotiate
   the client will need to send a header like
       Authorization: Negotiate YY.....
   to authenticate itself to the server
2. Proxy Authentication. The Web Server responses with
       HTTP/1.1 407 Proxy Authentication Required 
       Proxy-Authenticate: Negotiate
   the client will need to send a header like
       Proxy-Authorization: Negotiate YY.....
   to authenticate itself to the proxy server

The new codes support both types of authentication.


How to use the new feature
==========================

There is no new public API function involved in the new feature, but
several configurations are needed to perform a success communication:

1. Since the SPNEGO mechanism will call the Kerberos V5 login module to
   do real works. Kerberos configurations are needed. which includes:

   a) Some way to provide Kerberos realm and KDC address. This can be
      achieved with the Java system property java.security.krb5.realm
      and java.security.krb5.kdc. For example:
            java -Djava.security.krb5.realm=REALM_NAME \
                 -Djava.security.krb5.kdc=kdc.realm.name \
                 ClassName

   b) A JAAS config file denoting what login module to use. HTTP SPNEGO
      codes will look for the standard GSS_INITIATE_ENTRY entry named
      "com.sun.security.jgss.initiate".

      For example, you can provide a file spnegoLogin.conf:
          com.sun.security.jgss.initiate {
              com.sun.security.auth.module.Krb5LoginModule 
                  required useTicketCache=true;
          };
      and run java with:
            java -Djava.security.krb5.realm=REALM_NAME \
                 -Djava.security.krb5.kdc=kdc.realm.name \
                 -Djava.security.auth.login.config=spnegoLogin.conf \
                 ClassName


      Another JAAS login entry "http.auth.negotiate.server" is defined
      to be used by the server side.

2. Just like other HTTP authentication scheme, the client can provide
   a customized java.net.Authenticator to feed username and password to
   the HTTP SPNEGO module when they are needed (e.g. there is no keytab
   cache available). The only authentication information needed to be
   checked in your Authenticator is the scheme which can be retrieved
   with getRequestingScheme(). The value should be "Negotiate". 

   This means your Authenticator implementation will look like:

    class MyAuthenticator extends Authenticator {

	public PasswordAuthentication getPasswordAuthentication () {
            if (getRequestingScheme().equalsIgnoreCase("negotiate")) {
                String krb5user;
                char[] krb5pass;
                // get krb5user and krb5pass in your own way
                ....
                return (new PasswordAuthentication (krb6user, 
                            krb5pass.toCharArray()));
            } else {
                ....
            }
	}
    }

3. The client can still provide system property http.auth.preference to
   denote that a certain scheme should always be used as long as the
   server request for it. You can use "SPNEGO" or "Kerberos" for this
   system property. "SPNEGO" means you prefer to challenge the Negotiate
   scheme using the GSS/SPNEGO mechanism; "Kerberos" means you prefer
   to challenge the Negotiate scheme using the GSS/Kerberos mechanism.
   Normally, when authenticating against a Microsoft product, you can
   use "SPNEGO". The value "Kerberos" also works for Microsoft servers.
   It's only needed when you encounter a server which knows Negotiate
   but doesn't know about SPNEGO.

   If http.auth.preference is not set, the internal order choosen is:
      GSS/SPNEGO -> Digest -> BTLM -> Basic

   Noticed that Kerberos does not appear in this list, since whenever
   Negotiate is supported, GSS/SPNEGO is always chosen.

4. If the server has provided more than one authentication schemes
   (including Negotiate), according to the processing order mentioned
   in the last section, Java will try to challenge the Negotiate scheme.
   However, if the protocol cannot be established successfully (e.g.
   The kerberos configuration is not correct, or the server's hostname
   is not recorded in the KDC principal DB, or the username and password
   provided by Authenticator is wrong),  then the 2nd strongest scheme
   will be automatically used. You can notice this behaviour in the test
   case: TEST_NAME="Authenticate fallback".

   Attention: If http.auth.preference is set to SPNEGO or Kerberos, then
   we assume you only want to try the Negotiate scheme even if it fails.
   we won't fallback to any other scheme and your program will result in
   throwing an IOException saying it receives a 401 or 407 error from
   the HTTP response. This behaviour can be observed in the test case:
   TEST_NAME="Authenticate no fallback"


Test
====

The test is a bash script spnegoTest, which makes use of the Java class 
WebGet. WebGet.java is included. To run the test, you need these files:

    spnegoTest
    spnegoLogin.conf       JAAS login config file
    spnegoLog.properties   logging config file

The test environment includes 1 or 2 KDC server, 1 or 2 Web server, and 
1 proxy server. The web server and the proxy server need to support 
multiple authentication schemes setting to test the fallback feature.

The environment variables set inside spnegoTest are:

    WWW_REALM       The Kerberos realm the Web server belongs to
    WWW_KDC         The Kerberos KDC for the WWW_REALM
    WWW_URL         The URL to test against. It should be protected with
                    Negotiate and Basic authentication

    PROXY_REALM     The Kerberos realm the proxy server belongs to
    PROXY_KDC       The Kerberos KDC for the PROXY_REALM
    PROXY_URL       The URL to test against, Should be available to
                    anonymous request
    PROXY_PARA      The proxy server setting. The proxy server should
                    prompt for Negotiate and Basic authentication

    GOOD_PASS       Correct user/pass for Basic authentication
    GOOD_KPASS      Correct user/pass for Kerberos
    BAD_PASS        Wrong user/pass for Basic authentication
    BAD_KPASS       Wrong user/pass for Kerberos

    WWW_TAB         The keytab file for WWW_REALM
    PROXY_TAB       The keytab file for PROXY_REALM
    TAB_PATH        The standard keytab cache file path

    FILE_CONTENT    The content of URL expected

The values set in spnegoTest reflect a temporary testing environment,
where we use MS-Windows 2000 Advanced Server as the KDC server and Web 
server, and MS ISA 2000 Server as the proxy server.

In order to test the using of keytab cache, you need to get the keytab
files before starting the test. The pathname of the 2 keytab files (one
for the WWW_REALM, the other for the PROXY_REALM) should be set inside
the test script spnegoTest as WWW_TAB and PROXY_TAB respectively. During
the test process, they will be copied to the system recognized place
(TAB_PATH) in turn.

This is a manual step since on most systems the kerberos realm is setup
in krb5.conf, and you need a root privilege to edit the it to get the 2
ticket cache files. Normally, the process will look like:

    # edit the krb5.conf using $WWW_REALM
    kinit www_user_name
    cp $TAB_PATH $WWW_TAB
    # edit the krb5.conf using $PROXY_REALM
    kinit proxy_user_name
    cp $TAB_PATH $PROXY_TAB

Fortunately, you normally will only need to do this once in a day.

However, on MS-Windows platform, the kinit tool provided with the JRE 
has command options including realm, KDC, principal name, and password,
thus make it possible to generate the keytab files from a batch script.

Finally, you can run the test with

    $ bash spnegoTest || echo $?

Other Java examples (source code examples)

Here is a short list of links related to this Java spnegoReadme source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.