Forum OpenACS Development: Re: RFC: External Authentication

Posted by Andrew Grumet on
Hi Lars,

Looking excellent. Thoughts and suggestions below. I apologize in advance for the length :-)

Terminology: I think Authority is much more descriptive than Domain. When a person logs in, they are saying, "I am Telly Monster". OpenACS asks them to prove it. When the driver forwards the username and password, they are forwarding it to a system that is authoritative about who is Telly Monster and who isn't.

Login screen: I see the benefits of the way you did it. Namely, everything is explicit and there's no need for guesswork. The user logs in with their username and, in theory, need not have an email address (some customers seem to care about this). Here's an alternative:

  What is your e-mail address? (text box)
  Have you logged in to Sesame Street Intranet before?
    No, I am a new user.
    Yes, my password is: (text box)

For new users, we link them to a form where they can specify their authority (using friendly prompts such as "I have an MIT login" instead of "") and input their username. Once they've authenticated, we can try to pull their profile information, ask them to verify it, and create the new local account. From then on, the user logs in with their email address, which gets translated to a username on the backend before calling the authenticator.

This should solve the problem that you mentioned about existing accounts with the same email address. The only real down side here is that the "username != email" adherents will be unhappy because we require an email address.

Account creation and password management: I wouldn't go too nutty with these in the early stages. It may actually be desirable, as a matter of policy, to forward the user on to a central system, just to be sure that they understand that their changes will propagate beyond the OpenACS instance they happen to be working in.

Login modes: the problem with a function call like this:

auth::authenticate -username -domain -password -secure:boolean
is that it assumes that you will always use a username and password. But we also know that other methods exist, such as the redirection-based systems (CAS and Passport) and client certificates. Hence the ad-hoc "login using CAS" button on your form. Still, this function is useful for password-based login and so should sit on any login page presented by the system.

To handle the more general case, in an ideal world we would replace the calls like this

set user_id [ad_conn user_id]
and this
with a single, service-contract-backed call that looks like this
set user_id [auth::get_user_id -require_valid_user:boolean]
Based on a configurable policy, this function could choose between using an OpenACS cookie, a client certificate, redirecting to a local sign-in page over HTTP or HTTPS, or redirecting to a central (e.g. CAS) sign-in page.

The down side, of course, is that making a change like this would require touching virtually every page in OpenACS. Ouch, probably not a weekend project. Still, this is my current thinking on the issue and I thought it was at least worth mentioning.

Security: There's something broken about having a middleman (e.g. OpenACS) between the user and the authority. Consider the Kerberos example, where we send our username and password over (hopefully) HTTPS and let OpenACS handle the actual Kerberos authentication. From a security pov, what we've done is to assert that a) HTTPS is an acceptable stand-in for Kerberos, and b) we trust the operators of the OpenACS instance to require HTTPS and implement it correctly.

I find this problematic but don't yet have the solution sketched out. I've written some code for another system that checks for HTTPS and tries to discourage the user from entering remotely-checked passwords if HTTPS is not present. What we probably need, long term, is a vocabulary for talking about trust levels, and a way for the various drivers to advertise their requirements (i.e. "I only accept passwords transmitted over 128-bit HTTPS or better").