Wordpress authenticating REST

This is a follow up to a post from earlier today about authenticating a REST call in WordPress that comes from an Android app.

Short question now - I added some logging, and I think the Android app is sending
a RS256 token, but that the WP side requires a HS256 token. I switched the auth0
client on the dashboard, but the Android is still getting tokens in the RS256 encoding.
Is there something more I need to do?

Longer treatise follows: I decided to write up everything I’ve learned over the the
past 5 days into a form that might help the next person. Since I’ve been stumbling
through in the dark, though, some of this might be wrong. However, if it seems helpful
to you, please feel free to improve your documentation.

Thanks!

Troubleshooting REST API authorization HTTP calls in WordPress

This is specifically for http requests coming from an external source
(e.g., a mobile app) and being recieved in WordPress. If it’s not working for you,
check through these possible failure points. This is the process I’ve gone
through, and while it hasn’t worked for me yet, maybe it will save a little time
for the next person.

  1. Do you have the WordPress auth0 plug-in instlled?

  2. Do you have the auth0 JWT plug-in installed? Install and let it set up automatically
    using the plug-in installed in step 0.

  3. Does your api use wp-json or the old wp-admin/admin-ajax? If it is not using wp-json,
    you will need to switch it over. See REST API Handbook | WordPress Developer Resources.

  4. Is the caller of your API getting a JWT token and adding to the http message using
    the Authorization header (i.e. what in curl would be
    -H "Authorization: Bearer )?

  5. On the WordPress side, are the headers of the http getting stripped out? You can
    see if they are stripped by adding this code (for instance, to functions.php):

add_filter( ‘rest_pre_dispatch’, ‘prefix_show_request_headers’, 10, 3 );

function prefix_show_request_headers( $result, $server, $request ) {
$result = $request->get_headers();
write_log($result);
return $result;
}

If they are being stripped out, you will need to figure out why, and fix it, possibly
by updating your .htaccess file in the wp directory and adding this line:

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

I know really nothing about this, so take this point in particular with some
consideration.

  1. Is the auth0 client you are using configured to use HS256 or RS256 encoding?
    The WordPress JWT plug-in only supports HS256, so you may need to switch the setting
    in the Client on the auth0 website.

  2. When all else files, add some logging to the JWT to see why it is failing. See the
    file in the plugins directory wp-jwt-auth/lib/php-jwt/Authentication/JWT.php. Find the
    function decode, which for me is on line 44. Instrument it with calls to error_log.
    Does it get a token? Does the token get discarded somewhere along the way because of
    some problem? If so, add logging to each of the throw instructions to figure out which
    one it was.

  3. Are you requiring REST authentication in WordPress? You can require it for your
    entire API with this hook:

/* Require authentication for REST calls.
See: Authentication | REST API Handbook | WordPress Developer Resources
*/

add_filter(‘rest_authentication_errors’, function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
return new WP_Error( ‘rest_not_logged_in’, ‘You are not currently logged in.’, array( ‘status’ => 401 ) );
}
return $result;
});

Thanks for providing additional information about your discoveries. In relation to the short-question the answer is an Android (native) application is treated as an OAuth 2.0 public client and as such the ID tokens are forced to use RS256 because HS256 implies the application would have to have access to the shared secret used to sign the token and the application can’t really maintain that information secret.

In addition, the ID token is only meant to be consumed by the client application and not to be used as means for API authorization. Although you could register the Wordpress API as a resource server in the API’s section of the Auth0 dashboard and in this way obtain JWT access tokens using HS256 by configuring the resource server to use that signing method this may not be sufficient because then you would have to have something in Wordpress that understand Auth0 issued access tokens (not ID tokens). I expanded on this issue on the answer provided to the other question you posted.

Quick note for anyone looking to accept Auth0 access tokens in WordPress … I wrote a guide here: