Hi Rhett,
Yes, you are right. The Guard class should allow for multiple challenge
schemes (although it would be more realistic to try them one at a time).
There could be a list of challenge scheme instances in the Guard. Each
of these challenge scheme instances could be associated with an
authentication provider (or list thereof) and an authorisation provider,
if appropriate. (This would be substantially different to the current
ChallengeScheme, though).
Best wishes,
Bruno.
Rhett Sutphin wrote:
Hi Bruno,
This general idea is good. I have one small objection, though: HTTP
allows multiple challenges per 401 response. This means you might want
to have a guard with parallel authentication checks. For this reason, I
don't think that subclassing Guard per authentication scheme (basic,
digest, etc.) is appropriate.
Rhett
On May 28, 2008, at 4:35 PM, Bruno Harbulot wrote:
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