Core Platform Team/Initiatives/OAuth2

Initiative Description

< Initiatives

Summary

Add OAuth 2.0 support to MediaWiki so that a MediaWiki instance may be used as an authentication source by a client. The first phase of this work will be to add to MediaWiki support necessary for Discourse to use a MediaWiki instance as an OAuth 2.0 authentication provider. The second phase of this work will be to add to MediaWiki support for generating API keys using OAuth 2.0. The code developed in Phase 1 must be designed to be extensible for support of the Phase 2 functionality.

Significance and Motivation

We need OAuth 2.0 to have single sign-on with Discourse https://www.discourse.org/plugins/oauth.html . Other systems use OAuth 2.0 or the related OpenID Connect for distributed authentication. OAuth 2.0 is a common way for APIs to integrate API keys. The gold standard for API authentication; many libraries and tools support OAuth 2.0. OAuth 2.0 has some significant implementation optimizations over OAuth 1.0.

Outcomes
  • Users can log into Discourse with their Wikimedia project identity
  • WMF can track API requests by client
  • WMF can disallow API requests by badly-behaved client
Baseline Metrics

None given

Target Metrics

None given

Stakeholders
  • Community Engagement/Community Relations (Discourse authentication)
  • Partnerships (for API keys)
  • Other API providers within the organization?
Known Dependencies/Blockers

None given

Epics, User Stories, and Requirements

< Initiatives

Epic 1 - Add OAuth2 support to MediaWiki for use by web-based clients

Personas:

  • Server: wiki that is used as an OAuth identity provider
  • Admin: administrator of a wiki used as an OAuth identity provider
  • Client: client web application that uses a wiki as the OAuth identity provider
  • User: user of a client web application requesting authentication

Non-functional requirements:

  • OAuth 1.0 and OAuth 2.0 must be able to coexist
  • Implementation in an extension: OAuth2
  • Code must be extensible to support API-based clients in Epic 2
  • The MediaWiki code should not depend upon a particular client in any way
  • Possibly test with Wikimedia-hosted Discourse instance
  • Security review of all new code
  • Implement on top of new MediaWiki REST API support, if possible
  • Use existing library, if possible
User Story Title User Story Description Priority Notes
1 Admin adds new client Admin runs a script to add a new OAuth 2.0 client to a MediaWiki instance
  • Pass in redirect URI for the client
    • for Discourse, this will be of the form https://DISCOURSE_HOST/auth/oauth2_basic/callback
  • Script generates client ID and secret and returns them
  • Script stores client ID and redirect URI in the MediaWiki database
  • Admin provides client ID, secret, authorization URL, and token URL to client to configure the client application
Must Have This could be a self-service interface in the future, but this is out of scope for this epic
2 Admin removes client Admin runs a script to remove an existing OAuth 2.0 client from a MediaWiki instance
  • Pass in client ID
  • Client ID and associated information are deleted
  • Indicate success or failure
Must Have
3 User requests login to client when user is already logged in to server (wiki)
  1. Client sends a request of the form:
    • https://WIKI_AUTH_ENDPOINT/auth?response_type=code&client_id=CLIENT_ID& scope=SCOPE&state=STATE
    • State is a random string generated by the client which will be sent back to the client.
  2. Server verifies that there is a logged-in user associated with the wiki
  3. User is presented with the authorization prompt (unless the client is whitelisted)
  4. If the user does not approve, an authentication failure is returned
  5. If the user approves:
    • Server generates authentication code
    • Server redirects back to the client with:
      • https://REDIRECT_URI/cb?code=AUTH_CODE&state=STATE
  6. Client sends a POST request to https://WIKI_AUTH_ENDPOINT/token with the following parameters
    • grant_type=authorization_code
    • code=AUTH_CODE
    • client_id=CLIENT_ID
    • client_secret=CLIENT_SECRET
  7. Server responds with and access token and expiration or an error
  8. Configurable optional step to get user information from the server
Must Have
4 User requests login to client when user is not already logged in to server (wiki) Same as 3 above except at step 2 the server must initiate a login workflow with the user. If the user is not able to login, and error is returned. If the user logs in correctly, the workflow above continues at step 3. Must Have
7 Admin whitelists client Admin whitelists client so that users do not have to accept the authorization dialog every time they login Optional


Epic 2 - Add OAuth 2.0 support to MediaWiki REST API

In Phabricator: https://phabricator.wikimedia.org/T234665

In this stage, we will use OAuth 2.0 as the primary authorization mechanism for the MediaWiki REST API.

Note: "client ID" is another word for "API key".

Personas:

  • Developer - a software developer that uses the MediaWiki REST API on their own behalf or on behalf of users
  • User - a person who reads, contributes to, curates or administrates a MediaWiki
ID Title Use Case Priority Notes
1 Client ID for Authorization As a Developer, I want to use a client ID as a bearer token for the REST API, to identify requests made on behalf of my company. Must Have This encompasses two requirements, at least one of which is required (TODO: check with PMs whether both are required):
  • Implementation of the client_credentials flow.   Done in current WIP patches.
  • Display a permanent access token when registering/updating consumers with oarc_owner_only set, as the OAuth 1 implementation already does.
2 Access Token for Authorization As a Developer, I want to use an access token as a bearer token for the REST API, to identify requests made on behalf of a user. Must Have Implement a SessionProvider, which may be as simple as doing the OAuth2 equivalent in place of MWOAuthSessionProvider lines 85–93.
3 Request new client ID As a Developer, I want to request a new client ID, to identify an application that uses the REST API. Must Have   Done in current WIP patches by reusing the existing m:Special:OAuthConsumerRegistration.
4 List client IDs As a Developer, I want to view a list of my existing client IDs, to know which IDs I have to use. Must Have   Done in current WIP patches by reusing the existing m:Special:OAuthConsumerRegistration.
5 Delete client ID As a Developer, I want to delete disable a client ID, so that I am no longer responsible for keeping it secure, since I no longer use it. Must Have Site admins can already disable (not delete) a consumer to the same effect via m:Special:OAuthManageConsumers. This functionality does not seem to be available to developers, it may need to be added to m:Special:OAuthConsumerRegistration. If so, it should apply to both 1.0a and 2.0.
6 List access tokens As a User, I want to view a list of all the access tokens I have approved, so that I can see what organizations have access to my account. Must Have   Done in current WIP patches by reusing the existing Special:OAuthManageMyGrants.
7 Delete access token As a User, I want to delete an access token, so that an organization I no longer approve cannot access my account. Must Have   Done in current WIP patches by reusing the existing Special:OAuthManageMyGrants.
8 Delete all access tokens As a User, I want to delete all access tokens, so that no organizations have access to my account, because I am concerned there may be a security problem. Optional Implement if time allows. A "delete all" button should be added to Special:OAuthManageMyGrants, and apply to both 1.0a and 2.0 access tokens.
9 Delete tokens on password change As a User, I want to delete all access tokens when I change my password, so that applications need to re-authorize. Optional Implement if time allows. This will require a change to MediaWiki core, abstracting the existing call at AuthManager.php line 909 to call a method on all registered SessionProviders. The SessionProvider base class would implement this method as a no-op. BotPasswordSessionProvider would implement it to do what line 909 does now. The OAuth SessionProvider implementation would also implement it.

Support for OAuth 2.0 in the Action API and Core REST API would be supported after implementation of Epic 2, since Epic 2 will provide a SessionProvider. In future epics, other APIs supported inside the organization would also support OAuth 2.0 authorization.

Time and Resource Estimates

< Initiatives

Estimated Start Date

201920Q1

Actual Start Date

None given

Estimated Completion Date

None given

Actual Completion Date

None given

Resource Estimates

This task should be comparable to Add WebAuthn 2FA to OATHAuth in resource requirements.

Collaborators

This work may be completed by a contractor.

Open Questions

< Initiatives

  • Supporting Open Source clients that can't keep an API key secret
  • Supporting 1-page Web clients that can't keep an API key secret
  • Should the Discourse login and API authorization requirements be conflated here?

Documentation Links

< Initiatives

Phabricator
Plans/RFCs
Other Documents

None given

Subpages