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)
Submit
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
"kerberos.mit.edu") 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
ad_maybe_redirect_for_registration
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").