Skip to content

Commit

Permalink
Add cron job to refresh jwks (#5)
Browse files Browse the repository at this point in the history
* Update ah-jwt-auth.php

* Update readme.txt

* Update readme.txt

* linting fixes

* Update whitespace and errors

* More linting

* More litning
  • Loading branch information
andrewheberle authored Nov 9, 2023
1 parent 1636bec commit d568e2f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 33 deletions.
2 changes: 1 addition & 1 deletion ah-jwt-auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @wordpress-plugin
* Plugin Name: AH JWT Auth
* Description: This plugin allows sign in to WordPress using a JSON Web Token (JWT) contained in a HTTP Header
* Version: 1.4.1
* Version: 1.5.0
* Author: Andrew Heberle
* Text Domain: ah-jwt-auth
* Author URI: https://github.com/andrewheberle/wordpress-ah-jwt-auth/
Expand Down
59 changes: 27 additions & 32 deletions includes/class-ahjwtauthsignin.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,64 +127,61 @@ public function ahjwtauth_admin_notice() {
}

/**
* Schedules the refresh of the JWKS via WP Cron
*
* @return void
*/
* Schedules the refresh of the JWKS via WP Cron
*
* @return void
*/
public function ahjwtauth_schedule_refresh_jwks() {
if (!wp_next_scheduled('ahjwtauth_refresh_jwks')) {
wp_schedule_event(time(), 'daily', 'ahjwtauth_refresh_jwks');
if ( ! wp_next_scheduled( 'ahjwtauth_refresh_jwks' ) ) {
wp_schedule_event( time(), 'daily', 'ahjwtauth_refresh_jwks' );
}
}

/**
* Retrieves the JWKS from the configured URL and saves it as a transient
*
* A value of false is returned on error
*
* A value of false is returned on error
*
* @return array an associative array containing the key set
*/
private function ahjwtauth_refresh_jwks() {
$jwks_url = get_option( 'ahjwtauth-jwks-url' );
if ( '' === $jwks_url ) {
return true;
}

// retrieve json from JWKS URL with caching.
$keys = get_transient( 'ahjwtauth_jwks' );

// transient existed
// Does transient exist?
if ( false !== $keys ) {
return $keys;
}

// if transient did not exist, attempt to get url.
$jwks_url = get_option( 'ahjwtauth-jwks-url' );
$response = wp_remote_get( $jwks_url );
if ( is_wp_error( $response ) ) {
$msg = 'error retrieving the JWKS URL';
$this->error = __( 'AH JWT Auth: ' . $msg, 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: ' . $msg );
$this->error = __( 'AH JWT Auth: error retrieving the JWKS URL', 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: error retrieving the JWKS URL' );
return false;
}

// grab response body
// grab response body.
$json = wp_remote_retrieve_body( $response );

// check that response was not empty
// check that response was not empty.
if ( '' === $json ) {
$msg = 'could not retrieve the specified JWKS URL';
$this->error = __( 'AH JWT Auth ' . $msg, 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: ' . $msg );
$this->error = __( 'AH JWT Auth could not retrieve the specified JWKS URL', 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: could not retrieve the specified JWKS URL' );
return false;
}

// try to decode json.
$jwks = @json_decode( $json, true );
if ( null === $jwks ) {
$msg = 'cannot decode the JSON retrieved from the JWKS URL';
$this->error = __( 'AH JWT Auth ' . $msg, 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: ' . $msg );
$this->error = __( 'AH JWT Auth cannot decode the JSON retrieved from the JWKS URL', 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: cannot decode the JSON retrieved from the JWKS URL' );
return false;
}

Expand All @@ -197,11 +194,11 @@ private function ahjwtauth_refresh_jwks() {
error_log( $json );
return false;
}
// cache JWKS for future

// cache JWKS for future.
set_transient( 'ahjwtauth_jwks', $keys, WEEK_IN_SECONDS );

// return key set
// return key set.
return $keys;
}

Expand All @@ -217,9 +214,8 @@ private function ahjwtauth_refresh_jwks() {
private function get_token() {
$jwt_header = $this->get_header();
if ( ! isset( $_SERVER[ $jwt_header ] ) ) {
$msg = 'the expected JWT was not found. Please double check your reverse proxy configuration.';
$this->warning = __( 'AH JWT Auth ' . $msg, 'ah-jwt-auth' );
error_log( 'AH JWT Auth: WARNING: ' . $msg );
$this->warning = __( 'AH JWT Auth the expected JWT was not found. Please double check your reverse proxy configuration.', 'ah-jwt-auth' );
error_log( 'AH JWT Auth: WARNING: the expected JWT was not found. Please double check your reverse proxy configuration.' );
return false;
}

Expand Down Expand Up @@ -250,9 +246,8 @@ private function verify_token( $jwt ) {
try {
$payload = JWT::decode( $jwt, $key );
} catch ( SignatureInvalidException $e ) {
$msg = 'Cannot verify the JWT. Please double check that your private secret or JWKS URL is configured correctly';
$this->error = __( 'AH JWT Auth: ' . $msg, 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: ' . $msg );
$this->error = __( 'AH JWT Auth: Cannot verify the JWT. Please double check that your private secret or JWKS URL is configured correctly', 'ah-jwt-auth' );
error_log( 'AH JWT Auth: ERROR: Cannot verify the JWT. Please double check that your private secret or JWKS URL is configured correctly' );
return false;
} catch ( Exception $e ) {
return false;
Expand All @@ -276,7 +271,7 @@ private function get_key() {
if ( '' !== $jwks_url ) {
return $this->ahjwtauth_refresh_jwks();
}

// otherwise use shared secret.
return new Key( get_option( 'ahjwtauth-private-secret' ), $this->get_alg() );
}
Expand Down
3 changes: 3 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ Currently only the HS256 and RS256 alorithms are supported.

== Changelog ==

= 1.5.0 =
* Add WP cron job to refresh JWKS daily

= 1.4.1 =
* Update dependencies to resolve security issue

Expand Down

0 comments on commit d568e2f

Please sign in to comment.