0N/A//
0N/A// weijun.wang@sun.com
0N/A
0N/AHTTP SPNEGO
0N/A===========
0N/A
0N/AJPlan 116: SPNEGO HTTP authentication
0N/A http://jplan.sfbay/feature/116)
0N/ARFE 6260531: SPNEGO HTTP authentication
0N/A http://monaco.sfbay/detail.jsf?cr=6260531)
0N/ACCC 6244039: more HTTP authentication schemes to support in Java
0N/A http://ccc.sfbay/6244039
0N/A
0N/A
0N/AWhat's HTTP SPNEGO
0N/A==================
0N/A
0N/AHTTP SPNEGO supports the Negotiate authentication scheme in an HTTP
0N/Acommunication. There are 2 types of authentication here:
0N/A
0N/A1. Web Authentication. The Web Server responses with
0N/A HTTP/1.1 401 Unauthorized
0N/A WWW-Authenticate: Negotiate
0N/A the client will need to send a header like
0N/A Authorization: Negotiate YY.....
0N/A to authenticate itself to the server
0N/A2. Proxy Authentication. The Web Server responses with
0N/A HTTP/1.1 407 Proxy Authentication Required
0N/A Proxy-Authenticate: Negotiate
0N/A the client will need to send a header like
0N/A Proxy-Authorization: Negotiate YY.....
0N/A to authenticate itself to the proxy server
0N/A
0N/AThe new codes support both types of authentication.
0N/A
0N/A
0N/AHow to use the new feature
0N/A==========================
0N/A
0N/AThere is no new public API function involved in the new feature, but
0N/Aseveral configurations are needed to perform a success communication:
0N/A
0N/A1. Since the SPNEGO mechanism will call the Kerberos V5 login module to
0N/A do real works. Kerberos configurations are needed. which includes:
0N/A
0N/A a) Some way to provide Kerberos realm and KDC address. This can be
0N/A achieved with the Java system property java.security.krb5.realm
0N/A and java.security.krb5.kdc. For example:
0N/A java -Djava.security.krb5.realm=REALM_NAME \
0N/A -Djava.security.krb5.kdc=kdc.realm.name \
0N/A ClassName
0N/A
0N/A b) A JAAS config file denoting what login module to use. HTTP SPNEGO
0N/A codes will look for the standard GSS_INITIATE_ENTRY entry named
0N/A "com.sun.security.jgss.initiate".
0N/A
0N/A For example, you can provide a file spnegoLogin.conf:
0N/A com.sun.security.jgss.initiate {
0N/A com.sun.security.auth.module.Krb5LoginModule
0N/A required useTicketCache=true;
0N/A };
0N/A and run java with:
0N/A java -Djava.security.krb5.realm=REALM_NAME \
0N/A -Djava.security.krb5.kdc=kdc.realm.name \
0N/A -Djava.security.auth.login.config=spnegoLogin.conf \
0N/A ClassName
0N/A
0N/A
0N/A Another JAAS login entry "http.auth.negotiate.server" is defined
0N/A to be used by the server side.
0N/A
0N/A2. Just like other HTTP authentication scheme, the client can provide
0N/A a customized java.net.Authenticator to feed username and password to
0N/A the HTTP SPNEGO module when they are needed (e.g. there is no keytab
0N/A cache available). The only authentication information needed to be
0N/A checked in your Authenticator is the scheme which can be retrieved
0N/A with getRequestingScheme(). The value should be "Negotiate".
0N/A
0N/A This means your Authenticator implementation will look like:
0N/A
0N/A class MyAuthenticator extends Authenticator {
0N/A
0N/A public PasswordAuthentication getPasswordAuthentication () {
0N/A if (getRequestingScheme().equalsIgnoreCase("negotiate")) {
0N/A String krb5user;
0N/A char[] krb5pass;
0N/A // get krb5user and krb5pass in your own way
0N/A ....
0N/A return (new PasswordAuthentication (krb6user,
0N/A krb5pass.toCharArray()));
0N/A } else {
0N/A ....
0N/A }
0N/A }
0N/A }
0N/A
0N/A3. The client can still provide system property http.auth.preference to
0N/A denote that a certain scheme should always be used as long as the
0N/A server request for it. You can use "SPNEGO" or "Kerberos" for this
0N/A system property. "SPNEGO" means you prefer to challenge the Negotiate
0N/A scheme using the GSS/SPNEGO mechanism; "Kerberos" means you prefer
0N/A to challenge the Negotiate scheme using the GSS/Kerberos mechanism.
0N/A Normally, when authenticating against a Microsoft product, you can
0N/A use "SPNEGO". The value "Kerberos" also works for Microsoft servers.
0N/A It's only needed when you encounter a server which knows Negotiate
0N/A but doesn't know about SPNEGO.
0N/A
0N/A If http.auth.preference is not set, the internal order choosen is:
0N/A GSS/SPNEGO -> Digest -> BTLM -> Basic
0N/A
0N/A Noticed that Kerberos does not appear in this list, since whenever
0N/A Negotiate is supported, GSS/SPNEGO is always chosen.
0N/A
0N/A4. If the server has provided more than one authentication schemes
0N/A (including Negotiate), according to the processing order mentioned
0N/A in the last section, Java will try to challenge the Negotiate scheme.
0N/A However, if the protocol cannot be established successfully (e.g.
0N/A The kerberos configuration is not correct, or the server's hostname
0N/A is not recorded in the KDC principal DB, or the username and password
0N/A provided by Authenticator is wrong), then the 2nd strongest scheme
0N/A will be automatically used. You can notice this behaviour in the test
0N/A case: TEST_NAME="Authenticate fallback".
0N/A
0N/A Attention: If http.auth.preference is set to SPNEGO or Kerberos, then
0N/A we assume you only want to try the Negotiate scheme even if it fails.
0N/A we won't fallback to any other scheme and your program will result in
0N/A throwing an IOException saying it receives a 401 or 407 error from
0N/A the HTTP response. This behaviour can be observed in the test case:
0N/A TEST_NAME="Authenticate no fallback"
0N/A
0N/A
0N/ATest
0N/A====
0N/A
0N/AThe test is a bash script spnegoTest, which makes use of the Java class
0N/AWebGet. WebGet.java is included. To run the test, you need these files:
0N/A
0N/A spnegoTest
0N/A spnegoLogin.conf JAAS login config file
0N/A spnegoLog.properties logging config file
0N/A
0N/AThe test environment includes 1 or 2 KDC server, 1 or 2 Web server, and
0N/A1 proxy server. The web server and the proxy server need to support
0N/Amultiple authentication schemes setting to test the fallback feature.
0N/A
0N/AThe environment variables set inside spnegoTest are:
0N/A
0N/A WWW_REALM The Kerberos realm the Web server belongs to
0N/A WWW_KDC The Kerberos KDC for the WWW_REALM
0N/A WWW_URL The URL to test against. It should be protected with
0N/A Negotiate and Basic authentication
0N/A
0N/A PROXY_REALM The Kerberos realm the proxy server belongs to
0N/A PROXY_KDC The Kerberos KDC for the PROXY_REALM
0N/A PROXY_URL The URL to test against, Should be available to
0N/A anonymous request
0N/A PROXY_PARA The proxy server setting. The proxy server should
0N/A prompt for Negotiate and Basic authentication
0N/A
0N/A GOOD_PASS Correct user/pass for Basic authentication
0N/A GOOD_KPASS Correct user/pass for Kerberos
0N/A BAD_PASS Wrong user/pass for Basic authentication
0N/A BAD_KPASS Wrong user/pass for Kerberos
0N/A
0N/A WWW_TAB The keytab file for WWW_REALM
0N/A PROXY_TAB The keytab file for PROXY_REALM
0N/A TAB_PATH The standard keytab cache file path
0N/A
0N/A FILE_CONTENT The content of URL expected
0N/A
0N/AThe values set in spnegoTest reflect a temporary testing environment,
0N/Awhere we use MS-Windows 2000 Advanced Server as the KDC server and Web
0N/Aserver, and MS ISA 2000 Server as the proxy server.
0N/A
0N/AIn order to test the using of keytab cache, you need to get the keytab
0N/Afiles before starting the test. The pathname of the 2 keytab files (one
0N/Afor the WWW_REALM, the other for the PROXY_REALM) should be set inside
0N/Athe test script spnegoTest as WWW_TAB and PROXY_TAB respectively. During
0N/Athe test process, they will be copied to the system recognized place
0N/A(TAB_PATH) in turn.
0N/A
0N/AThis is a manual step since on most systems the kerberos realm is setup
0N/Ain krb5.conf, and you need a root privilege to edit the it to get the 2
0N/Aticket cache files. Normally, the process will look like:
0N/A
0N/A # edit the krb5.conf using $WWW_REALM
0N/A kinit www_user_name
0N/A cp $TAB_PATH $WWW_TAB
0N/A # edit the krb5.conf using $PROXY_REALM
0N/A kinit proxy_user_name
0N/A cp $TAB_PATH $PROXY_TAB
0N/A
0N/AFortunately, you normally will only need to do this once in a day.
0N/A
0N/AHowever, on MS-Windows platform, the kinit tool provided with the JRE
0N/Ahas command options including realm, KDC, principal name, and password,
0N/Athus make it possible to generate the keytab files from a batch script.
0N/A
0N/AFinally, you can run the test with
0N/A
0N/A $ bash spnegoTest || echo $?