On Mar 31, 2009, at 12:47 AM, Michael McMahon wrote:
Max,
One question. Would this mechanism work for any possible GSS
security mechanism?
In other words, is all the information you need encapsulated inside
a single
GSSCredential object?
Yes, this object is enough to perform a delegated GSSContext
establishment. Of course, the requestGSSCredential() can also have the
same arguments as in requestPasswordAuthentication() so that the user-
provided method can take actions based on hostname etc.
Also, java.net.Authenticator was designed very much for the original
HTTP authentication
schemes (Basic and Digest) which is why it has all these methods for
getting
the hostname, port, domain "prompt" string etc and NTLM more or less
fits in with
this API as well.
Authenticator is also suitable for a normal Negotiate-scheme
authentication, which asks for username and password and then uses
JGSS-API to acquire a credential from the KDC server.
So, this is a different way of doing it, where a pre-established
credential is used
instead of a user being prompted to provide a username and password
based
on the parameters supplied by the protocol.
Correct, in this case, this credential is received from another party
(also thru JGSS-API) as a token, so there needs a new way to feed it
into the HTTP client.
At the very least, there would have to be a way to distinguish
between these two
modes of operation. But I am wondering if a separate class might be
more appropriate
(GSSAuthenticator). So, HttpURLConnection could check if a
GSSAuthenticator exists
then it would probe that object for the credential. otherwise it
would fall back to
the existing approach
Well, I think a username/password pair is also a kind of credential,
so it's quite natural to use a single class to provide all of them.
The fallback mechanism can be implemented in the class, if username/
password is needed, the requestPasswordAuthentication() method can be
called.
An alternative design: How about not intrude the setDefault() method
but make the GSSCredential itself a static field?
class Authenticator {
private GSSCredential cred;
public synchronized static GSSCredential
setGSSCredential(GSSCredential c) {
GSSCredential old = cred;
cred = c;
return old;
}
public static GSSCredential requestGSSCredential() {
return cred;
}
}
One problem with extending Authenticator is that the plugin has a
fixed Authenticator
implementation, that only handles usernames and passwords, and it
might not
want to use this new mechanism.
I see. I wish the Authenticator was designed as cascade-able.
Thanks
Max
- Michael
Max (Weijun) Wang wrote:
Ping again, any suggestions?
Thanks
Max
On Nov 25, 2008, at 3:01 PM, Weijun Wang wrote:
Hi All
The current implementation of HTTP Negotiate authentication has not
enabled credential delegation (it simply acquires a new one using
either
a cached TGT or username/password from Authenticator). This means
that
in a multi-tier application, a middle tier cannot start an HTTP
request
(to the backend server) on behalf of the client.
Currently, java.net.Authenticator can only authenticate using a
username/password pair, but cannot use an established credential.
I'm suggesting the following updates:
1. In java.net.Authenticator, add 2 methods
protected GSSCredential getGSSCredential() { // To be overrided
return null;
}
public static GSSCredential requestGSSCredential() {
Authenticator a = theAuthenticator;
if (a == null) {
return null;
} else {
return a.getGSSCredential();
}
}
2. In the implementation of the HTTP Negotiate auth scheme
(sun.net.www.protocol.http.NegotiatorImpl),
GSSCredential deleg = Authenticator.requestGSSCredential();
context = manager.createContext(serverName,
oid,
deleg, // this used to be null
GSSContext.DEFAULT_LIFETIME);
Then, when an application developer is creating a GSS server that
wants
to start an HTTP request using a delegated credential, she can
write:
// establish the GSSContext
final GSSCredential deleg = context.getDelegCred();
Authenticator.setDefault(new Authenticator() {
@Override
protected GSSCredential getGSSCredential() {
return deleg;
}
});
new URL("http://somewhere").openConnection().getInputStream();
What's your comment?
Thanks
Max