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


Reply via email to