WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/08/2020 10:12:02 PM (12 months ago)
Author:
TimothyBlynJacobs
Message:

REST API: Introduce Application Passwords for API authentication.

In WordPress 4.4 the REST API was first introduced. A few releases later in WordPress 4.7, the Content API endpoints were added, paving the way for Gutenberg and countless in-site experiences. In the intervening years, numerous plugins have built on top of the REST API. Many developers shared a common frustration, the lack of external authentication to the REST API.

This commit introduces Application Passwords to allow users to connect to external applications to their WordPress website. Users can generate individual passwords for each application, allowing for easy revocation and activity monitoring. An authorization flow is introduced to make the connection flow simple for users and application developers.

Application Passwords uses Basic Authentication, and by default is only available over an SSL connection.

Props georgestephanis, kasparsd, timothyblynjacobs, afercia, akkspro, andraganescu, arippberger, aristath, austyfrosty, ayesh, batmoo, bradyvercher, brianhenryie, helen, ipstenu, jeffmatson, jeffpaul, joostdevalk, joshlevinson, kadamwhite, kjbenk, koke, michael-arestad, Otto42, pekz0r, salzano, spacedmonkey, valendesigns.
Fixes #42790.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/load.php

    r49023 r49109  
    8787        $PHP_SELF            = $_SERVER['PHP_SELF'];
    8888    }
     89
     90    wp_populate_basic_auth_from_authorization_header();
     91}
     92
     93/**
     94 * Populates the Basic Auth server details from the Authorization header.
     95 *
     96 * Some servers running in CGI or FastCGI mode don't pass the Authorization
     97 * header on to WordPress.  If it's been rewritten to the `HTTP_AUTHORIZATION` header,
     98 * fill in the proper $_SERVER variables instead.
     99 *
     100 * @since 5.6.0
     101 */
     102function wp_populate_basic_auth_from_authorization_header() {
     103    // If we don't have anything to pull from, return early.
     104    if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) && ! isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) {
     105        return;
     106    }
     107
     108    // If either PHP_AUTH key is already set, do nothing.
     109    if ( isset( $_SERVER['PHP_AUTH_USER'] ) || isset( $_SERVER['PHP_AUTH_PW'] ) ) {
     110        return;
     111    }
     112
     113    // From our prior conditional, one of these must be set.
     114    $header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
     115
     116    // Test to make sure the pattern matches expected.
     117    if ( ! preg_match( '%^Basic [a-z\d/+]*={0,2}$%i', $header ) ) {
     118        return;
     119    }
     120
     121    // Removing `Basic ` the token would start six characters in.
     122    $token    = substr( $header, 6 );
     123    $userpass = base64_decode( $token );
     124
     125    list( $user, $pass ) = explode( ':', $userpass );
     126
     127    // Now shove them in the proper keys where we're expecting later on.
     128    $_SERVER['PHP_AUTH_USER'] = $user;
     129    $_SERVER['PHP_AUTH_PW']   = $pass;
    89130}
    90131
Note: See TracChangeset for help on using the changeset viewer.