On Thu, Mar 25, 2010 at 12:27 AM, Ryan Lane <rlane32(a)gmail.com> wrote:
I'd like to discuss the proposed change to the
authentication plugin
system (
http://www.mediawiki.org/wiki/ExternalAuth). As proposed, I
don't see how I'll be able to keep most of the functionality in the
LDAP extension.
It isn't a change, it's an addition. AuthPlugin will be kept
indefinitely, certainly at least until all users in trunk are
obsoleted by equivalent ExtAuth plugins (which may well be never).
I don't disagree that policy and implementation
shouldn't be mixed,
but core shouldn't be making all policy decisions. For instance, there
is an option in the LDAP extension ($wgLDAPDisableAutoCreate) that
disables auto-creation, but still allows auto-authentication.
Essentially, it says, if the user exists in LDAP, but not in the local
directory, don't automatically create the local account. Some
administrators want to create accounts for users in the wiki locally,
even though they already have accounts in LDAP.
First off, if this is desirable for LDAP, it's desirable for other
auth systems too. Therefore, in ExtAuth, this feature would be added
to the core code, *not* individual extensions, so that it could be
used by *all* backends. The LDAP-specific stuff should only deal with
stuff that is *really* specific to LDAP, like connecting to the LDAP
server and mapping MediaWiki auth info to however LDAP stores things.
Second, I'm not sure what you mean by "disables auto-creation, but
still allows auto-authentication". The user must be authenticated as
*some* user that exists in the MediaWiki database, no? How does
auto-authentication work in this case?
This might be the same as $wgAutocreatePolicy. The default is
'login', which autocreates accounts if a user logs in, their auth
information doesn't match any local account, and it does match an
external account. You can also set it to 'never', which never
autocreates local accounts (so they have to be manually linked, which
doesn't work yet); and 'view', which will try to autocreate from
cookies or such if supported by the backend.
Will getGroups() assign users to whatever groups the
backend returns?
The way I'm currently doing this is adding users to groups if they are
available groups in the wiki (if they've been defined in
$wgGroupPermissions). I don't use auto-promote at all.
You mean, you just take the group name strings returned by LDAP and
assign them to the user as MediaWiki groups? That's an interesting
idea, provided there are no conflicts. It would be a lot simpler than
using auto-promote. However, it could cause problems if group names
were weird, like with spaces or something, since a lot of code
probably assumes they look like typical MediaWiki group names.
Still, I think this is a better approach. Currently this isn't
actually implemented at all in ExtAuth, so it could be changed to the
method you describe easily enough.
The LDAP plugin can add users to the LDAP database. Is
this also going
to support that?
That's a possible feature, although I don't think it's in any of my
design documents. For many backends it would be impractical, but it
would make sense for LDAP. I mostly designed this to allow
authentication on my site's wiki from vBulletin, another web app, so
the design is probably skewed toward that, but I'm pretty sure it's
flexible enough that it could be adjusted to support LDAP well.
The LDAP plugin allows a user to authenticate with one
username, but
have the username created be something else. This is absolutely a
must-have for auto-authentication, where a user might authenticate
with Kerberos or an SSL certificate. If a user authenticates with an
SSL certificate, their username may be something insane, like a
numeric ID with special characters. The LDAP plugin would search the
LDAP directory for another attribute that should be used for the
username. Notice that you don't necessarily want to treat the
auto-auth name as an ID either. You may pull both a new username, and
a unique ID from the LDAP server; this is an especially likely
scenario in a large organization, where a user may have a global
unique ID, but in some places they may have a locally unique ID (think
mergers).
This is part of the design for ExternalAuth, although it hasn't yet
been implemented. It's necessary for any backend that doesn't have
username restrictions as rigid as MediaWiki, or that uses
incomprehensible usernames. Even if you're just authenticating to an
external MediaWiki, it's necessary to resolve conflicts. (In
particular, this is necessary for vBulletin, since that permits
characters like / in names, but it's not so essential, since most
names don't have them -- which is why it's not implemented yet.)
There are situations where newFromId( $id ) and
getId() won't work.
Active Directory (AD) is a case where it is unlikely to work for most
people. By default AD does not allow anonymous searches. There are two
ways to handle this:
1. Use a proxy agent (AD administrators *hate* this)
2. Bind as the user first
In the second case, newFromId( $id ), and getId() will only work if
authenticate( $password ) is called first. In fact, many things
require the user to be authenticated before another action can happen.
From the LDAP server's perspective, MediaWiki *is* the user binding.
From ExternalAuth's perspective, an "id"
can be any unique, stable
identifier. It's used to store the information
"MediaWiki user 13099
is associated to external user 32769". A "username" is expected to be
something human-readable, which is actually used for login, but which
may change from time to time (due to renaming). id's are stored in a
varchar(255) and are not required to be numeric.
In particular, I think LDAP could just use an id equal to the
username, since LDAP usernames are supposed to be stable, right?
A few things I'd really like to see fixed with any
new system are:
1. Extensions being able to display error messages (bug 16524)
This sounds like a good idea. An implementation idea would be to add
a new method ExternalUser::getAuthenticationErrors(), like
Title::getUserPermissionsErrors(), and use that in core code instead
of authenticate(). The new method could wrap authenticate() in the
base class, so classes that didn't need such fancy control could still
just use authenticate().
2. Ability to rename a local account when the external
account is renamed
Sounds like a good idea, but how would you detect that the external
account was renamed? Would you expect the external auth source to
push this info to MediaWiki, or should MediaWiki detect it when the
user next logs in? How should MediaWiki detect it -- remember the
external username, and update the local one if the external one is
different from what was remembered? Presumably it would just abort
silently if there's some conflict (e.g., new name not usable by
MediaWiki, or already taken).
The current ExtAuth implementation only stores the foreign id locally,
not the name. If the external name changes, and the new external name
isn't taken locally, you can log in to MediaWiki using either the new
or old name, IIRC -- if you try the new one, it will authenticate you
as the external user, then notice that that already has a local
account and log you in as that. But your MediaWiki username will
remain the same as the old name unless you're renamed on MediaWiki.
This works for now, but would be nice to change.
3. Local group name size increased in the schema (bug
11057) so that
all external groups can be synced properly
I forgot that MediaWiki group names have to be so short. Maybe
autopromote is a better idea after all for backends that might have
long group names. But that should be fixable, anyway, I hope.