Skip to content

Application Passwords #13

@georgestephanis

Description

@georgestephanis

Repo: https://github.com/wordpress/application-passwords

@TimothyBJacobs asked me to write up an issue about the work already done on Application Passwords, so here we go:

User Flow : New App

The flow is as simple as an app linking to your.site/wp-admin/?path=auth_app with a number of optional get strings appended to it. This ensures that if the user isn't already logged in, the request arguments get preserved through the authentication flow:

  • app_name (required) - The human readable identifier for your app. This will be the name of the generated application password, so structure it like ... "WordPress Mobile App on iPhone 12" for uniqueness between multiple versions. If omitted, the user will be required to provide an application name.
  • success_url (recommended) - The URL that you'd like the user to be sent to if they approve the connection. Two GET variables will be appended when they are passed back -- user_login and password -- these credentials can then be used for API calls. If the success_url variable is omitted, a password will be generated and displayed to the user, to manually enter into your application.
  • reject_url (optional) - If included, the user will get sent there if they reject the connection. If omitted, the user will be sent to the success_url, with ?success=false appended to the end. If the success_url is omitted, the user will be sent to their dashboard.

The UI looks something like this:

4350f5c8-ff2f-11e6-9399-8bbbe3fb44b5

and when the user completes the flow, they can be redirected back to the url they came from, or even directly back into the app requesting authorization via custom app protocols.

The flow is accomplished and made smoother via javascript / ajax requests, however will operate just fine via traditional form submissions if JS is disabled in the browser for any reason.

Managing existing app passwords

The user profile page panel for managing application passwords looks like this:

434fcd60-ff2f-11e6-938f-5a49609fff4b

It can be used to generate new passwords directly, but for auth requests from an external website or app it's much better ux to use the previous flow.

The table is managed and updated via jQuery for dom queries/insertions/deletions, and wp.template for generating the markup. It should be trivially rewritable into React if there's a need to expand React usage in the admin.

Data

The generated application passwords are 24 characters long to ensure over 128 bits of entropy (we're actually at over 142 bits of entropy -- 62^24), and have their hashes stored in usermeta under the _application_passwords key.

Application Passwords are stored in the database as an array of arrays under the aforementioned key.

Each entry consists of the following properties:

  • name -- The designated application name given when the password was created. Not guaranteed to be unique.
  • password -- The password's hash, via wp_hash_password()
  • created -- The time() that the password was created.
  • last_used -- The time() that the password was used most recently. Can be useful for finding and clearing out old passwords no longer in use.
  • last_ip -- The $_SERVER['REMOTE_ADDR'] that most recently used the application password. This can be a very useful audit trail to identify if it has been used improperly.

Authentication

Application Passwords explicitly only work for REST API or XML-RPC authentication. They can not be used and will not function when attempting an interactive login via wp-login.php or the like.

REST API Support

The existing application-passwords plugin fully supports the REST API, offering endpoints to list, add new application passwords, and delete one or all application passwords for a given user.

https://github.com/WordPress/application-passwords/blob/0e71ecdad32eb54c7bfebac0553482e72f3134aa/class.application-passwords.php#L73-L293

DON'T PANIC

The application-passwords repository has a lot of random files in it. Most of these were added for automated testing and such and can be ignored. The only relevant files in it to understand what's going on are:

  • application-passwords.css -- general styles
  • application-passwords.js -- js for the profile page listing ui
  • application-passwords.php -- basic plugin loader -- just loads the class and kicks it off
  • auth-app.js -- js for the auth flow ui
  • class.application-passwords-list-table.php -- list table for the profile page -- minimal
  • class.application-passwords.php -- most of the hard work. well commented, phpdoc, etc.

In Summation

Some of the most relevant wins I see here with Application Passwords are:

  • Application Passwords can only be used for API requests, never for getting a full wp-admin login.
  • Doesn't require password storage. Applications integrating with WordPress never see the user's actual password.
  • Application Passwords are high-entropy, and fully revokable.
  • Very easy implementation. No libraries needed, as the username and password can be passed via standard basic auth (as supported by curl already). Handles FastCGI incompatability by using .htaccess to rewrite to a different authentication header, and then catches via a fallback.
  • Backward Compatible with XML-RPC! The generated credentials can be used as a drop in replacement for legacy apps that use XML-RPC, and also enables apps doing new integrations to query legacy XML-RPC endpoints if needed for any reason.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions