[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: authentication architecture.

From: Mark C. Chu-Carroll <mcc_at_watson.ibm.com>
Date: 2001-07-26 22:34:57 CEST

I'm trying not to be too annoying with contributions about how our
project does things, but I think this might be useful to you.
We've just gone through a similar discussion in Synedra, with similar
constraints. In particular, we share the layering constraint where we
want no backward calls from the server to the client. At the same time,
we (like subversion) want full access through the network, and we don't
want to be transmitting passwords around *at all*.

Our solution is object based, but I think there's a decent
pointer/structure based equivalent. And I think it meets the
constraints that Ben was talking about. And it's got one other big
advantage: you can add or alter authentication mechanisms without
requiring corresponding changes to client code.

The idea is that we use "authentication components". An authentication
component is an object with a set of methods that can be used by the
client to prove that it has the appropriate credentials. In Java,
a trivial example is an authenticator for password authentication looks
like:

        class TrivialPasswordAuthenticator {
            public void setUser(String user);
            public void setPassword(String pass);
            public RepositoryHandle authenticate();
            }

When a client connects, it can request from the server a list of
available authentication methods. If the client can handle any of the
methods provided by the server, then it requests an authenticator of
the correct type, and uses that to authenticate itself.

This gets pretty nice when you consider challenge methods; an
HTTP digest style challenge can be done using a class with
a signature like the following:

class HTTP_Authenticator {
   HTTP_Authenticator(java.sql.Connection dbconn, String reposname);
   Repository authenticate() throws PriviledgeException;
   void setUserName(String name);
   void setClientNonce(String cn);
   void setURI(String uri);
   String getURI(String uri);
   void setOperation(String op);
   String getServerNonce();
   String getRealm();
   void setChallengeCode(byte hashcode[]);
}

The client is expected to know the protocol for the authenticator. In
this
case, it can retrieve the information it needs to compute the challenge
result; and then it can provide the client nonce and the challenge
result
to the server before finally authenticating.

Multiphase challenge can be done using an authenticator that returns a
second-stage authenticator from the "authenticate" call.

So... A typical client interacting with this authentication method
would do:
        Set<String> auths = getAuthenticators();
        if (auths.contains("password")) {
            PasswordAuthenticator pa = getAuthenticator("password");
            pa.setUser(username);
            .. prompt user for password ..
            pa.setPassword(password);
            RepositoryHandle handle = pa.authenticate();
            ...
         }

Again, this method manages to provide solid authentication, with the
ability
to extend the set of recognized authenticators, but without requiring
changes
to old client. It should be fairly easy to provide this kind of
functionality
using closure style structs.

        -Mark

--
Mark Craig Chu-Carroll,  IBM T.J. Watson Research Center 
<mcc@watson.ibm.com>
*** The Synedra project:
http://domino.research.ibm.com/synedra/synedra.nsf
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:33 2006

This is an archived mail posted to the Subversion Dev mailing list.