Tmeister / wp-api-jwt-auth

A simple plugin to add JSON Web Token (JWT) Authentication to WP REST API
GNU General Public License v2.0
558 stars 161 forks source link

Unable to Implement 'RS256' Algorithm #280

Closed LadisWasharum closed 1 year ago

LadisWasharum commented 1 year ago

Issue Description:

I'm experiencing problems while trying to implement the 'RS256' algorithm with the jwt_authalgorithm filter for JWT. When the filter is applied, I encounter HTTP 500 error and the token response is broken. When the RS256 filter is not applied, and my other filters for JWT are enabled (see bottom of post)_, the token generates with the required data, just not using RS256.

Here is the filter I am using that is causing the issue (other filters I am using with no issues at bottom):

add_filter('jwt_auth_algorithm', function() {
    return 'RS256';
});

Environment:

Steps to Reproduce:

  1. I installed and activated the WP-API-JWT-Auth plugin on my WordPress site.
  2. I attempted to use the 'RS256' algorithm with the jwt_auth_algorithm filter.

Expected Behavior:

I expected the plugin to use the 'RS256' algorithm for JWT without any issues.

Actual Behavior:

Applying the jwt_authalgorithm filter results in HTTP 500 error for API response in postman when generating a token (token generates fine without 'RS256' filter enabled)_.

Error Logs:

Error log when RS256 enabled and token is called via Postman (token response is not successful):

PHP Notice: Undefined index: REDIRECT_HTTP_AUTHORIZATION in //jwt-authentication-for-wp-rest-api/public/class-jwt-auth-public.php on line 225 PHP Warning: openssl_sign(): supplied key param cannot be coerced into a private key in //jwt-authentication-for-wp-rest-api/includes/vendor/firebase/php-jwt/src/JWT.php on line 237 PHP Fatal error: Uncaught DomainException: OpenSSL unable to sign data in //jwt-authentication-for-wp-rest-api/includes/vendor/firebase/php-jwt/src/JWT.php:239

Error log when RS256 is not enabled and token is called via Postman (token response is successful):

PHP Notice: Undefined index: REDIRECT_HTTP_AUTHORIZATION in //jwt-authentication-for-wp-rest-api/public/class-jwt-auth-public.php on line 225

.htaccess File:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Additional Information:

I am using the current filters without issues to meet the requirements of firebase:


add_filter('jwt_auth_not_before', function() {
    return time();
});

add_filter('jwt_auth_expire', function() {
    return time() + 3600; // Expires in 1 hour
});

add_filter( 'jwt_auth_token_before_sign', function( $token, $user ) {
    $service_account_email = '<firebase-service-email>'; // Replace with your service account email

    $token = array(
        'iss' => $service_account_email,
        'sub' => $service_account_email,
        'aud' => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
        'iat' => time(),
        'exp' => time() + 3600, // Expires in 1 hour
        'uid' => $user->data->ID, // The unique identifier of the user
    );

    return $token;
}, 10, 2);

Any guidance on how to resolve these issues and implement 'RS256' with your plugin would be greatly appreciated. Thanks in advance!

LadisWasharum commented 1 year ago

I solved this issue. The plugin works, RS256 is just not documented and required running around in circles for a bit.

You need to edit your wp-config file!

The documentation says to add the following to wp-config:

define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');

and it says you can use a key string from

https://api.wordpress.org/secret-key/1.1/salt/

The issue is that RS256 requires an RSA key, which you can generate from here and paste as is: https://travistidwell.com/jsencrypt/demo/

For those of you who are using firebase for authentication with this plugin, you will need to make sure to download the private key generated for firebase, open up the file, and copy everything within the private_key. Another important note, you will need to replace the single quotation marks

'your-top-secret-key'

with double quotation marks

"your-top-secret-key"

So the final should look like this:

define('JWT_AUTH_SECRET_KEY', "-----BEGIN PRIVATE KEY-----\nyour-top-secret-key\n-----END PRIVATE KEY-----\n");