jeffw16 / JWTAuth

Adds support for using JSON Web Tokens to log in to MediaWiki.
MIT License
3 stars 5 forks source link

JWTAuth

Adds support for using JSON Web Tokens to log in to MediaWiki.

Dependencies

The following requirements need to be met before installing JWTAuth:

Installation

First and foremost, you need to meet the above dependency requirements.

Add the following to LocalSettings.php, being sure to fill in the proper values where needed:

wfLoadExtension( 'JWTAuth' );
$wgJWTAuthAlgorithm = ''; // can be: HS256, RS256, EdDSA
$wgJWTAuthKey = ''; // Depends on which algorithm you are using
// For RS256 the key is the JWK in PEM format, extracted from the JWKS at https://yourdomain.com/auth/realms/servername/protocol/openid-connect/certs
$wgJWTGroupMapping = [
  // one group can map to multiple MediaWiki groups...
  'customgroup1' => [
    'sysop', 'bureaucrat'
  ],
  // ...or just one MediaWiki group.
  'customgroup2' => 'sysop'
];

If you need to debug the JWT being sent, turn on debugging by adding $wgJWTAuthDebugMode = true; to your LocalSettings.php.

Go to the extension's folder (probably under extensions/JWTAuth) and run composer update --no-dev to install JWTAuth's dependencies.

Integration

The following procedure must be followed to successfully authenticate a user into the wiki:

  1. A JWT claim must be well formed and encoded into the JWT payload format using the key that has already been agreed upon.
  2. Find the path to your wiki's location of Special:JWTLogin. For instance, if your wiki is under https://wiki.example.com and $wgArticlePath = "/wiki/$1"; then the location is https://wiki.example.com/wiki/Special:JWTLogin.
  3. The payload must be POSTed to this aforementioned URL. The URL should have a parameter called Authorization with the content Bearer: JWTTOKENHERE. For instance, Bearer: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYSIsImF1ZCI6Im5hIiwiaXNzIjoibmEiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMiwibmJmIjoxNTE2MjM5MDIyLCJleHAiOjE3MTYyMzkwODJ9.gQbzrsJAVtEFjh-a4RwqZtSJ-IHxVvl2cj66Vkfljr.
  4. The payload must conform to the claim names promulgated by IANA: https://www.iana.org/assignments/jwt/jwt.xhtml

Below are the claims that are required by the JWTAuth extension. If any of these are missing, the authentication process will fail. If you are unsure of what these mean, or the allowed values for them, please visit https://jwt.io for more details.

You can put nonsense (but nonempty) values for iss, aud, and sub, as they are not checked by JWTAuth, but our JWT decoding library (Firebase JWT) will cause the auth process to fail if they are not set.

The following claims are optional, but are highly recommended because they will be added to users' profiles:

As of 0.1.0, most of these claim names cannot be changed to match the token generator's preferences because these claim names are standard conventions. The party generating the token is responsible for sending well-formed responses that conform to internet standards. The group claims name can be changed to match your preferences by modifying $wgJWTGroupClaimsName.

If you want to assign groups to a user, pass them in, separated by commas, by using the groups claim. For instance, "groups": "customgroup1,customgroup2". Then, define the mapping in $wgJWTGroupMapping like it was done in the example config shown above.

Testing out JWTAuth using a simple HTML form

If you want to try testing out JWTAuth using a simple form, put the following HTML somewhere and use it to POST the JWT to your wiki. Be sure to replace PATH_TO_WIKI with the URL to your wiki.

<form method="post" action="https://PATH_TO_WIKI/wiki/Special:JWTLogin">
  <input type="text" name="Authorization" value="Bearer: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYSIsImF1ZCI6Im5hIiwiaXNzIjoibmEiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMiwibmJmIjoxNTE2MjM5MDIyLCJleHAiOjE3MTYyMzkwODJ9.gQbzrsJAVtEFjh-a4RwqZtSJ-IHxVvl2cj66VkfljrY">
  <input type="submit">
</form>

Notes for developers

Thank you for contributing to this extension!

All code should follow standard coding conventions used across the industry.

Please use 4 spaces in lieu of 1 tab character.

This project does not follow the standard MediaWiki code style because:

  1. It makes use of arcane coding conventions not followed in other programming languages (or even other PHP projects, for that matter);
  2. It is difficult to enable lints that support arcane code styles on a wide variety of IDEs; and
  3. Developers who work on many codebases across different languages and companies/organizations don't need to (and don't want to) keep track of 3957302859673028503749382934 different coding styles.

TL;DR: Please don't use the MediaWiki coding style. :)