[security-dev 00429]: Request for comment: How to enable credentials delegation in HTTP Negotiate?
Max (Weijun) Wang
Weijun.Wang at Sun.COM
Mon Mar 30 21:32:42 PDT 2009
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
>>>
>>
>
More information about the net-dev
mailing list