Apr 11, 2010

HTTP basic authentication. Credential caching

By default, when using authentication for connections, each host/port (or proxy host/port) is associated with a single set of credentials. A key for the credentials is a string specified as follows: A:[B:]C:D:E[:F] Between 4 and 6 fields separated by ":" where the fields have the following meaning: A is "s" or "p" for server or proxy authentication respectively B is optional and is "D", "B", or "N" for digest, basic or ntlm auth. C is either "http" or "https" D is the hostname E is the port number F is optional and if present is the realm. After being initially requested (and assuming the credentials are valid), any subsequent HttpURLConnections on that host/port (or proxy host/port) will use the same credentials. There are some situations where you may wish to have different sets of authentication credentials for connections going to the same host/port. Unfortunately this caching behaviour is hardcoded in JDK and could not be changed via any configuration. The only solution I have found was using of custom implementation for this cache. This method implies dealing with Sun proprietary classes.
    
import sun.net.www.protocol.http.AuthCache;
import sun.net.www.protocol.http.AuthCacheValue;

.....

AuthCacheValue.setAuthCache(new AuthCache() {
      
      public void remove(String arg0, AuthCacheValue arg1) {
      }
      
      public void put(String arg0, AuthCacheValue arg1) {
      }
      
      public AuthCacheValue get(String arg0, String arg1) {
        return null;
      }
    });
    
    Authenticator.setDefault(new Authenticator() {
      @Override
      protected PasswordAuthentication getPasswordAuthentication() {
        return new MyPasswordAuthentication(...);
      }
    });
In this case no credential are cached at all. It works for me. If you know another way to disable caching of credentials, please share it with me.

4 comments:

Rajat said...

Hi,

I tried your solution, but it didn't worked for me.

Please share more details.

Thanks

Illya Yalovyy said...

This source code is essential. What doesn't work in particular? In what environment are you trying it? Give example of your code. The quick recommendation is try to debug your code and study the source code of the JDK.

Unknown said...

Hiya.

I'm actually seeing behavior that even incorrect credentials are cached. Is that consistent with your findings?

Also, have you come across a non-JVM-specific way of dealing with this? Surely the Oracle JDK can't mandate that the only way to clear the auth cache is to kill the JVM process(though this appears to be the case while cruising through some of the com.sun code).

S,
ALR

Unknown said...

Hiya.

I'm actually seeing behavior that even incorrect credentials are cached. Is that consistent with your findings?

Also, have you come across a non-JVM-specific way of dealing with this? Surely the Oracle JDK can't mandate that the only way to clear the auth cache is to kill the JVM process(though this appears to be the case while cruising through some of the com.sun code).

S,
ALR