Extension:OAuth

The OAuth extension implements OAuth 1.0a in MediaWiki. It allows third party developers to securely develop applications (Consumer), which users can grant a limited set of permissions (Grants) to, so that the application can use the MediaWiki API on the user's behalf.

Requirements

 * OAuth relies on memcached for temporary tokens and sessions
 * Currently, only mysql database backend is supported

Using OAuth
In order to use OAuth to make MediaWiki api calls on behalf of another user, you need to:
 * 1) Register your application (Consumer), and get it approved by a wiki admin
 * 2) Get the user's permission, and get a set of authorized tokens
 * 3) When making api calls, include an Authorization: HTTP header, which identify the user and prove your possession of the authorized token

Developing your App
An example php script that handles the technical portions of this can be found here: User:CSteipp/OAuth_demo_client

An example using flask-oauth: Setting_up_Flask_cgi_app_as_a_tool/OAuth

There is also a generic Python library (on top of requests-oauthlib): MediaWiki-OAuth

There is also a PHP library to make implementing PHP clients easier, using the same interfaces as MediaWiki-OAuth: mwoauth-php. A demo to use the library is included in the repo here.

Register your Consumer

 * To propose your Consumer, you must have the 'mwoauthproposeconsumer' right
 * On WMF wikis, this right is given to autoconfirmed accounts
 * Visit Special:OAuthConsumerRegistration/propose
 * Fill in the required information
 * Name and description: This is what your users will see when authorizing your application, along with your wiki username
 * Version: The permissions you grant are tied to a specific version of your application. You will increase the version number if you need to change grants later.
 * Callback URL: This is the url where user will be redirected after they have authorized your application in their web browser, with the verification code added as a GET parameter, and the temporary token to identify the user to you.
 * For bots, you will probably want to redirect the user to a page that will show the verification code back to the user, and have them cut-and-paste the verification code into the bot.
 * Grants: These are the permissions you application will use, if your user also has these rights.
 * Unless this is a demo application, you will need "Basic Rights" to use the MediaWiki api
 * Users can revoke individual grants from your application, so your application always needs to handle permission errors gracefully
 * Restrictions: The OAuth specification recommends that OAuth Consumers are restricted to a limited set of IP addresses. This protects your users, in case your secret key is compromised, and an attacker attempts to use the MediaWiki api on behalf of your users. This can be updated after your application is approved.

Get Your User's Permission
For a user (who you have authenticated in your application) to allow your application to use MediaWiki on their behalf, you will need to complete the 3-step OAuth protocol, and store the user-specific token and secret for that user. You will use the user-specific token, along with your application's token and secret on each API call, for MediaWiki to act on behalf of the user.


 * Step 1: Obtain a temporary token by calling Special:OAuth/initiate from your application
 * Caveat: When constructing your url, use /w/index.php?title=Special:OAuth/initiate instead of /wiki/Special:OAuth/initiate, because MediaWiki silently will create a title parameter that isn't included in your signature calculation.
 * Step 2: Direct the user's browser to /wiki/Special:OAuth/authorize, with the token from Step #1 as a GET parameter
 * Step 3: After the user has authorized your application and been redirected back to your application, exchange the verification code and the temporary token for a permanent authorized token

Identify the User (optional)
Your application can optionally identify the user who has authorized it by making a signed request to Special:OAuth/identify. The request is signed with both your application's key/secret, and the authorized token/secret that you obtained in step 3 above.

MediaWiki returns a Json Web Token (JWT), which has been signed with your Consumer Secret, which was issued to you when you registered your consumer. To identify the user, you must: If the JWT has a valid signature, and you have verified the JWT, you can know that the MediaWiki user had the following attributes at the time of the check:
 * Check the signature on the JWT (you can use the JWT::decode function included in the extension's source). This prevents an attacker from tampering with the content of the JWT. The JWT will be signed with the HS256 (hmac sha256) signature. You should reject any JWT's that specify a different signature scheme (such as, "none").
 * Verify that the token was issued by the expected wiki, to your application, within a valid time frame, with a valid nonce. This prevents an attacker from responding to your request with an old JWT, or a JWT for another consumer. The token contains fields for you to validate:
 * iss: The issuing MediaWiki's $wgCanonicalServer
 * aud: Your application's Consumer Key
 * iat: Timestamp the token was issued at
 * exp: Timestamp when this token expires
 * nonce: The nonce from your OAuth request
 * username: The MediaWiki username
 * sub: The MediaWiki user_id
 * editcount: The user's edit count
 * confirmed_email: The user has a confirmed email set in MediaWiki
 * registered: The date when the user registered
 * groups: A list of groups to which the user belongs
 * rights: A list of user rights that this user has been granted on the wiki

Use the API, setting Authorization header

 * MediaWiki requires that you use the http Authorization header, instead of including the OAuth parameters your GET or POST values
 * You will still need to get and use CSRF tokens to make edits, just as if you were using the API normally. Your application does not need to keep track of the wiki's session cookie-- the OAuth extension will create and use a session based on the user's authorized token, which will last up to 1 hour
 * Your API calls will be limited to the user rights that were both given to the user, and granted by the user to your application during the authorization step
 * Edits from your application will be tagged with your Consumer's id number