AzureAD / active-directory-b2c-wordpress-plugin-openidconnect

A plugin for WordPress that allows users to authenticate with Azure AD B2C using OpenID Connect.
MIT License
31 stars 28 forks source link

Autoload causes fatal errors #5

Closed wgengarelly closed 7 years ago

wgengarelly commented 8 years ago

I was excited to find this plugin since I am working on securing a Wordpress site with Azure AD B2C. It seems like the intent is to create a production caliber Wordpress plugin, which I believe will be useful.

However, I ran into some problems getting it to work. The biggest problem was related to the autoload.php functionality. The autoload function is registered with "spl_autoload_register", but the logic does not restrict any class names. As a result, the logic for this plugin will run for any other plugin, theme, or the core Wordpress code that also uses spl_autoload_register. Since external classes are not found in this plugin's directory, fatal errors like the following are generated:

Warning: require_once(class-nav-menu-roles.php): failed to open stream: No such file or directory in /home4/public_html/wp-content/plugins/active-directory-b2c-wordpress-plugin-openidconnect-master/autoload.php on line 14. Fatal error: require_once(): Failed opening required 'class-nav-menu-roles.php'

Warning: require_once(class-wp-filesystem-direct.php): failed to open stream: No such file or directory in /www/wp-content/plugins/active-directory-b2c-wordpress-plugin-openidconnect-master/autoload.php on line 25. Fatal error: require_once(): Failed opening required 'class-wp-filesystem-direct.php'

In my case, since the Nav Menu Roles plugin logic runs on every page, the entire site was down with fatal errors on every request.

To reproduce this issue, try installing the Nav Menu Roles plugin (https://wordpress.org/plugins/nav-menu-roles/) on a Wordpress site that also has the Azure AD B2C plugin activated. The error should occur during the install since some of the core Wordpress code uses spl_autoload.

I’ve found that a good practice to follow when autoloading is to write the function so the logic only runs when the class belongs to the plugin. This can be achieved by looking at namespaces or prefixes, and looking for the file within the plugin directory.

The PHP Framework Interop Group (PHP-FIG) has a set of PHP Standards Recommendations (PSRs) that many developers follow. PSR-4 is dedicated to the Autoloader, and there is a lot of good information and best practices in the recommendation and examples: https://github.com/php-fig/fig-standards/blob/master/accepted/psr-4-autoloader.md

I was able to get the plugin working by modifying autoload.php. At the beginning of the function, I added code to ensure that the class includes the prefix for B2C classes, or for the Crypt and Math classes:

// only try to autoload AD B2C classes or their vendor dependencies
if ( 0 !== strpos( $class, 'B2C' ) && 0 !== strpos( $class, 'Crypt' ) && 0 !== strpos ( $class, 'Math' ) ) {
    return;
}

At the end of the class, I also checked to see if the class was found in the plugin directory:

$plugin_directory = plugin_dir_path( __FILE__ );
if ( file_exists( $plugin_directory.$class_filename ) ) {
    require_once $class_filename;
}

Would you like a pull request with these changes?

gsacavdm commented 7 years ago

Long overdue, but thanks for submitting PR #6 for this. I'm closing the issue.