Most of the recent discussion related to implementing this RfC is happening in Gerrit 195297; you are encouraged to follow it if you are interested.
Talk:Requests for comment/AuthManager
I do believe that this new approach provides a number of benefits. I would like to describe our use case to make sure that is can be effectively handled by this approach.
We have a centralized identity manager that handles authentication requests for our enterprise. However, not every authenticated user is actually authorized to use every resource. The authentication decision is centralized, but the authorization decision is local to the wiki. I intentionally named Extension:PluggableAuth that instead of PluggableAuthentication or PluggableAuthorization, since both the authentication and authorization pieces are pluggable. Authenication and authorizatoin are handled a bit differently. Further, different wikis, despite sharing the centralized authentication service, will have different sets of authorized users and may, in fact, use different authorization models.
For example, I have written an authorization plugin that we use with PluggableAuth that uses a database table to maintain a list of email addresses of users authorized to use the wiki. There is a special page used by a sysop to populate that table. This works because 1) the centralized identity management system guarantees that email addresses are persistent and uniquely identify users and 2) the number of users on the wikis in question are small enough not to overburden the sysop with authorization management requests. We are considering future authorization extensions that are more robust and can more easily handle larger numbers of users. For example, I could imagine an authorization extension that would provide a rule engine and the ability to authorize or de-authorize users on a domain level rather than an individual user level.
Perhaps, following the model of the RFC, this can be handled with a REDIRECT response by the AuthenticationProvider that communicates with the central identity manager to another chained AuthenticationProvider that handles the local authorization decision. Is that consistent with the intent of REDIRECT? (In this case, I would sort of prefer that they be called AuthProviders, since sometimes the decision is whether the user can be authenticated and sometimes whether an authenticated user is authorized - but I can probably live slightly unhappily with this.)
The part I do not like about my current approach that I would love to improve is that the authorization piece requires a user object to already be constructed. Therefore, we end up with our user table littered with users who attempted to access the wiki and were authenticated but were not authorized. (I could probably, with a little bit of work, restructure the PluggableAuth code around this.) It sounds like the RFC would handle this better, since the user would not be created in the database (if I understand it correctly) until after all of the AuthenticationProviders have had their say.
However, here's the key part: the second AuthenticationProvider (the one handling authorization) needs user identifying information provided by the first AuthenticationProvider. That is, in our case, we do not know the system-wide unique identifier of the user until after the centralized identity provider has been contacted. Would the RFC be able to accommodate user identifying information being passed between AuthenticationProviders? I realize that this creates a perhaps uncomfortable dependency between AuthenticationProviders, since the second AuthenticationProvider would not be able to give a positive result in the absence of this information, but it is necessary in order for this approach to work.
Thank you for your work on this RFC.
We are very deliberately ignoring authz at this point in order to focus on authn. The end result of an interaction with the AuthManager (which we debated calling AuthenticationManager and still may in implementation) is only an authenticated session with a pointer to the correct local User.
We agree that the authz components of the existing system need to be cleaned up as well, but as was pointed out in previous discussions of the prior iterations of this RfC, changing all the things at once is very ambitious and likely to end up prolonging the implementation or even stalling the project all together.
Once we can get this RfC's implementation underway I'm very interested in continuing by helping draft an authorization proposal that would work along similar lines to handle the authz side of the problem.
OK, understood. However, it would be good to be sure that nothing in the proposed approach precludes handling the use case described above.
Your use of "authentication" and "authorization" is confusing, as often happens when thinking about authn and authz. You can often break down "authn" into further "authn+authz" pieces to the point of craziness like "authn says 'This user is Anomie' and authz says 'This user is allowed to be Anomie, based on the password they supplied'". It sounds to me like you may have broken things down to that point. From MediaWiki's perspective both authenticating the user against the central identity manager and checking if that centrally-authenticated user is authorized to access this wiki are part of authn, so why not just do both steps inside a single AuthenticationProvider? But if you didn't want to do it that way, you could have your first step be the PrimaryAuthenticationProvider and your second step be a SecondaryAuthenticationProvider to fit into the model of this RFC.
You might still need an authz component to your extension if the central identity provider also has functionality like CentralAuth's global groups, but that's outside the scope of the current RFC.
Authentication: proving that the user is who they say they are. Authorization: proving that a particular user is allowed to access a particular resource. In the use case I described above, "not every authenticated user is actually authorized to use every resource. The authentication decision is centralized, but the authorization decision is local to the wiki." That is, our wikis exist within our corporate enterprise. Authentication, proving that the user is who they say they are, is handled by a centralized corporate resource that is able to verify the identity of all users. This enables single sign-on within the enterprise. The authorization decision, however - determining which users are allowed to use which wikis - cannot be handled centrally. We have a large number of topic-based wikis, each potentially with its own list of authorized users or rules for how to determine if a user is authorized. I gave one example above of using a list of email addresses. Another example is accessing the corporate LDAP directory to only admit users who belong to a particular department. This is not the password situation you describe above.
If using a PrimaryAuthenticationProvider for authentication with the centralized authority and using a SecondaryAuthenticationProvider (despite the name) for the local authorization decision fits within the model of the RFC, that is helpful. However, I specified two items above that it was unclear to me would be supported by this model: 1) the user account should not be created in the database until after both authentication and authorization are decided in the affirmative and 2) it is possible to pass enough information to uniquely identify the user from the PrimaryAuthenicationProvider to the SecondaryAuthenticationProvider.
I was asked to provide feedback on whether the RFC would work for our use case. I have described our use case and my questions regarding whether it will be supported. If our use case is outside the scope of the current RFC, then we will still need to use other means to satisfy it.
1) the user account should not be created in the database until after both authentication and authorization are decided in the affirmative and 2) it is possible to pass enough information to uniquely identify the user from the PrimaryAuthenicationProvider to the SecondaryAuthenticationProvider
I think @Anomie:'s suggestion of looking at this slightly differently in your particular use case is a good one. If you think of authentication from the point of view of a particular wiki with rules that say that only a subset of all users who exist in the external user pool are valid, then to authenticate to the wiki the user must have a valid username and password combo as validated by the external source and the user must also match additional constrains such as being associated with a white list of allowable users (email address in list and/or LDAP group membership in your example above).
In the scenario that you describe, the proper fit in the AuthManager framework with highest reuse would likely be to consider the whitelist behavior to be similar to a 2-factor auth scenario which would be implemented as a SecondaryAuthenticationProvider. Currently we have only imagined the secondary providers receiving the AuthenticationRequest object and not some stub User object created by an AuthenticationProvider. This would likely mean that you would need to be able to lookup whitelist membership starting with only the username provided in the request rather than passing additional data from provider to provider. It would also be possible to combine the two activities into a single AuthenticationProvider.
As someone who is helping a corporation use MediaWiki, I think Cindy's take on this should be viewed as representative of those who use MediaWiki in large organizations.
The argument is often made here (on MW.o) that if you want more control over authorization than MW gives you, then you should use a CMS. This argument ignores a sizable number of users who have decided on and use MW because of the workflows and culture that it enables that a CMS is not designed for.
Cindy works on a large corporate wiki farm and has the ability to implement a lot of what she wants. It would be good to ensure that her insights are addressed here.
She may be conflating Authz and Authn in ways that the WMF doesn't need to worry about for Wikipedia, but for those of us without a sizable userbase to do the work that WMF relies on community for, it makes sense to be sure that the design of the code can accommodate our needs at these early stages.
Relation with authentication service & security considerations
There seems to be a good amount of overlap here with what's proposed in the SOA auth RFC. The difference seems to be that this proposal aims to build a new authentication layer inside of MediaWiki, while the SOA auth proposal aims to protect sensitive user data and provide authentication APIs that can be used by other services as well.
Could you say something about how you plan to address those issues?
We see the changes proposed in this RfC as a prerequisite for integrating any new external authentication service into MediaWiki in a meaningful way. The SOA auth system when built would be integrated with MediaWiki via a new AuthenticationProvider that communicated with the SOA auth system on those wikis that chose to deploy it.
AuthStack -> AuthManager
This RfC has been renamed and updated as part of a friendly takeover by the MediaWiki Core team. We have tried to build on Parent5446's foundation and flesh out many additional details of how and why certain changes are being proposed. As always, comments and suggestions welcome.
April 9th discussion
This RfC is due to be discussed briefly on April 9th; join us!
- 22:07:39 <sumanah> OK, let's move on to AuthStack
- 22:07:45 <sumanah> #topic Authstack
- 22:07:49 <sumanah> #link https://www.mediawiki.org/wiki/Requests_for_comment/AuthStack
- 22:07:55 <sumanah> #info Tyler updated this earlier this year. He responded to a request and "reduced the scope of the RFC by removing the Permissions infrastructure and the ClientSession class." So we could use a fresh opinion.
- 22:08:00 <sumanah> (parent5446 that is)
- 22:08:50 <brion> oh authn/z…. what a fun world :D
- 22:09:09 <sumanah> csteipp: you probably have opinions ^
- 22:09:17 <parent5446> Yeah, so the goal of this is to get rid of the ChainedAuth hook in LdapAuthentication
- 22:09:29 <parent5446> B/c it's basically a hack to allow more than one authnz method
- 22:09:55 <sumanah> (while I wait for other people to respond: I am writing to you from a hallway at PyCon, the Python convention. It is in Montreal, so I have unearthed the French I learned 15 years ago. Je voudrais acheter un bilet!)
- 22:10:06 <csteipp> I really do like the concept in general. The ldap especially makes a compelling use case.
- 22:10:30 <parent5446> It also tries to adopt the whole service-oriented architecture theme we have going
- 22:11:26 <brion> i’ll defer to those who have been poking at auth code more recently on this one, but it sounds good in theory
- 22:11:40 <brion> old AuthPlugin was a bit hacky and was done without benefit of experience in using said plugins :D
- 22:12:07 <brion> any implications for LDAP, CentralAuth, etc?
- 22:12:10 <parent5446> I do need feedback on one thing. Is it OK to use ExternalUser as a class name? Because it is the same class name as the recently removed ExternalUser experiment.
- 22:12:25 * brion whispers “namespaces!”
- 22:12:47 <parent5446> Lol, I can put this stuff in a namespace if we support putting core classes in namespaces
- 22:13:34 <brion> parent5446: worst case we can change the class name i guess :)
- 22:13:35 <csteipp> Was there an "ExternalUser experiment"? I missed that. The name sounds ok to me, but "ExternalAuthUser" would be fine too
- 22:13:49 <brion> actually i’d kinda prefer ExternalAuthUser, that’s more descriptive
- 22:13:55 <parent5446> Yeah, I think it was removed in a previous version. I don't think anybody ever used it
- 22:14:13 <sumanah> peut-etre Tim pense un quelque chose ici <----- (terrible high school French for "maybe TimStarling thinks something here")
- 22:14:22 <parent5446> I'd support ExternalAuthUser as well.
- 22:14:44 <sumanah> (since he was the one to comment in July)
- 22:14:51 <csteipp> Definitely look into the bug that we have open about initializing users using session setup... just to avoid the situation we're currently in
- 22:14:53 <brion> #info some agreement to changing ExternalUser to ExternalAuthUser for clarity and to avoid potential conflict
- 22:15:46 * sumanah waits another minute for Tim to speak up before we move on to Abstract table definitions (which should be quick)
- 22:16:03 <brion> :)
- 22:16:16 <sumanah> hmm, anything else to #info here?
- 22:16:50 <sumanah> #info a few people like the idea in general
- 22:16:51 <parent5446> Once I finish up the Password patch I'll start working on AuthStack code
- 22:16:52 <brion> #info people seem to like the general idea — likely to proceed?
- 22:16:54 <MaxSem> #info Everyone believes it's generally a good idea
- 22:16:58 <brion> :D
- 22:17:06 <sumanah> #info <parent5446> Once I finish up the Password patch I'll start working on AuthStack code
- 22:17:16 <sumanah> All right
- 22:18:14 <csteipp> parent5446: bug 41201
- 22:18:51 <parent5446> csteipp: Thanks. That's for the the ClientSession part
- some agreement to changing ExternalUser to ExternalAuthUser for clarity and to avoid potential conflict (brion, 22:14:53)
- a few people like the idea in general (sumanah, 22:16:50)
- people seem to like the general idea — likely to proceed? (brion, 22:16:52)
- Everyone believes it's generally a good idea (MaxSem, 22:16:54)
- <parent5446> Once I finish up the Password patch I'll start working on AuthStack code (sumanah, 22:17:06)
Have you had time to work on this?
Just a little tiny bit. Unfortunately the password patch has not been merged yet, so that's my main focus. But I have some code stored in a branch on my computer with an outline for this.
Any update? :-)
Sorry. No update yet. I'll work on it this week and see what I can do.
Great, thanks Tyler!
I'm concerned that this may be too large a project for you to implement and get reviewed in one chunk. I discussed this RFC in the MediaWiki Core Team meeting today, and Chad suggested asking you to reduce its scope, which seems to me like a good way to make it more manageable, for us and for you. In particular, the Permissions interface appears to be largely independent and could be left for a later RFC. Also, the Password component, especially the resolution of bug 28419 (which now has 79 comments) seems like a distinct and potentially controversial unit of work.
Understandable. Not sure what was going through my head when I thought it was a good idea to put them all together.
Have you had time to reduce the scope of the RFC as suggested by Tim? If not, are you planning to do so?
Hey, yeah. I just now did some last minute cleanup, but I reduced the scope of the RFC by removing the Permissions infrastructure and the ClientSession class.