Hi all,
Following the discussion on the authentication scheme a few days ago,
I've been looking at
- Access to connector authentication
http://restlet.tigris.org/issues/show_bug.cgi?id=503
- Add notion of realm
http://restlet.tigris.org/issues/show_bug.cgi?id=504
- Add support for Guards based password files encrypted by htpasswd
http://restlet.tigris.org/issues/show_bug.cgi?id=485
I've also been looking a bit more generally at Guards, and this raised a
few questions/observations/suggestions, which I suppose could be part of
this discussion.
I get the impression that a few things in the Guard API are there for
historical reasons (I suppose the first implementation of Guard only
supported HTTP BASIC).
I'm trying to think of a Guard class that would be sufficiently abstract
to model various types of authentication, not only HTTP BASIC/DIGEST,
but also SSL client-certificates, SPNEGO Kerberos, Shibboleth and
perhaps forms.
I'm just not sure that the notions of Realm (i.e. BASIC/DIGEST realms),
Secrets (known Map), SecretResolver, DomainURI and Nonce all belong
there. What I mean is that perhaps there should be subclasses of Guard
per authentication mechanism.
In contrast, the solution suggested to issue 485 (htpasswd) is a
subclass, and perhaps there should be the notion of a
authentication-provider instead. Similarly, I'm not familiar with the
OAuth Guard, but I get the impression it doesn't make much use of Realm,
Secrets, etc.
For example, in Apache Httpd, it's possible to configure mod_auth_basic
[1][2] with several authentication providers used in to authenticate the
user, for example file (htpasswd) or ldap. There's also a mechanism that
In one of the machines I've set up, I've used something where it's
possible to fake the SSL client certificate as a username in the file.
(It's thus possible to have cert-based authentication and LDAP
username/password as a fallback mechanism.)
There would need to be at least two categories of password-based
providers: the ones from which the secret can be extracted (required for
DIGEST) and the others.
It's just a vague suggestion, but there could be something like this:
* AuthProvider (abstract?)
* SslAuthProvider extends AuthProvider
(checking the subject DN or perhaps other things)
* PasswordAuthProvider extends AuthProvider
(of which the secret itself can't be obtained)
- checkPassword(String username, char[] password): boolean
* ExtractablePasswordAuthProvider extends PasswordAuthProvider
(one that can reveal the secret as well)
- getPassword(String username): char[]
There could be more concrete implementations:
* PasswordMapAuthProvider extends ExtractablePasswordAuthProvider
(more or less the same as the current secret map).
* LdapAuthProvider extends PasswordAuthProvider
(which checks the password against an existing LDAP server)
* HtpasswdAuthProvider extends PasswordAuthProvider
(which checks the password from a file as described in issue 485)
* JdbcAuthProvider extends ExtractablePasswordAuthProvider
(which would get the password from a database)
Then, perhaps a (more) abstract Guard and then classes like these:
* HttpBasicGuard extends Guard
(constructed or somehow provided with a PasswordAuthProvider, it
doesn't actually need to check against a known secret)
* HttpDigestGuard extends Guard
(constructed or somehow provider with an
ExtractablePasswordAuthProvider, since it would need to know the password)
These Guards could also take a list of providers rather than a single
one, perhaps to have a fallback solution.
All this being said, this wouldn't cover the case I was mentioning
earlier of SSL-cert falling back to HTTP BASIC/LDAP, so I'd need to
think a bit more about this.
In addition, perhaps the AuthProviders could be used in relation to the
Realms, etc. They could provide a suitable instance of Principal (e.g.
LdapPrincipal, KerberosPrincipal, ... when JAAS is used). There's
clearly some overlap between this notion of authentication-providers
(similar to Apache Httpd) and the notion of realms (as in Tomcat or Jetty).
This would clearly require a bit more thoughts, but does the general
idea seem sensible?
Best wishes,
Bruno.
[1] http://httpd.apache.org/docs/2.2/mod/mod_auth_basic.html
[2] http://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html