Basic Authorization Header Missing fix not working
shockthealien opened this issue · comments
Hi
I followed your instructions to fix the issue and added the code to the .htaccess file but I am still getting the error. Are there any other things that could be causing this?
Thanks
I've run into the same problem. With one of the latest WordPress changes (some time after August/September 2019) something must have changed inside WordPress' core. I assume there is something going on with the priorities of the filters/hooks for the REST subsystem.
Application Passwords relies on the constant REST_REQUEST (class.application-passwords.php::authenticate()) which is false, even if an HTTP request to one of my /wp-json endpoints has been triggered. For unknown reasons, the wp-includes/rest-api.php::rest_api_loaded() method is not been called, so that the REST_REQUEST constant doesn't get defined.
I've fixed this issue temporarily by adding a hook for the application_password_is_api_request filter:
add_filter('application_password_is_api_request', function($api_request) {
if (empty($api_request)) {
return strpos($_SERVER['REQUEST_URI'], '/wp-json/') !== false;
}
return $api_request;
}, 10, 1);
@schakko thanks for the reply. That sounds promising.
Does that hook go in the .htaccess file too? (sorry for my ignorance)
@shockthealien The hook goes into one of your wp-content/plugins files, e.g.
- create a new file at wp-content/plugins/hook/index.php
- paste the following into to index.php
<?php
/*
Plugin Name: My plugin
Description: My plugin
Version: 1.0.0
*/
add_filter('application_password_is_api_request', function($api_request) {
if (empty($api_request)) {
return strpos($_SERVER['REQUEST_URI'], '/wp-json/') !== false;
}
return $api_request;
}, 10, 1);
@schakko Thanks! I’ll give that a try
@schakko I added that to my sites and it doesn't seem to be working for me sadly
I followed your instructions to fix the issue and added the code to the .htaccess file but I am still getting the error. Are there any other things that could be causing this?
@shockthealien Could it be that the webserver is using something other than Apache -- maybe Nginx? That would have a different way to configure things.
I've run into the same problem. With one of the latest WordPress changes (some time after August/September 2019) something must have changed inside WordPress' core.
@schakko Could you please elaborate on what you mean? The plugin is using the determine_current_user
filter to process the HTTP authentication headers for the REST requests. The application_password_is_api_request
filter is used only for the "regular" login requests to disallow application passwords for regular logins.
It’s a possibility. The server is a shared one from 1and1. How can I find out for sure? If that’s the case is it a no-go?
@shockthealien Check the Site Health report under the "Info" tab at the top of the page. It should have all the server details.
Thanks I’ll have a look tomorrow and post the results
@schakko Could you please elaborate on what you mean? The plugin is using the
determine_current_user
filter to process the HTTP authentication headers for the REST requests. Theapplication_password_is_api_request
filter is used only for the "regular" login requests to disallow application passwords for regular logins.
Sure. When I am accessing my REST endpoint (/wp-json/...):
- the parameter $input_user for rest_api_auth_handler is empty.
- self::authenticate is executed
- $api_request is null because REST_REQUEST is not defined
- apply_filters( 'application_password_is_api_request', $api_request ) evaluates to false, so the empty $input_user variable is returned
- rest_api_auth_handler returns an empty value, as $input_user is empty
Thanks for that detailed explanation @schakko!
It looks like the first time the wp_get_current_user()
is called is in line 609 of wp-includes/class-wp.php
during WP->init()
in wp-settings.php
:
#0 Application_Passwords::authenticate(, admin, ) called at [/var/www/html/wp-content/plugins/application-passwords/class.application-passwords.php:264]
--
| #1 Application_Passwords::rest_api_auth_handler() called at [/var/www/html/wp-includes/class-wp-hook.php:286]
| #2 WP_Hook->apply_filters(, Array ([0] => )) called at [/var/www/html/wp-includes/plugin.php:208]
| #3 apply_filters(determine_current_user, ) called at [/var/www/html/wp-includes/user.php:2698]
| #4 _wp_get_current_user() called at [/var/www/html/wp-includes/pluggable.php:69]
| #5 wp_get_current_user() called at [/var/www/html/wp-includes/class-wp.php:609]
| #6 WP->init() called at [/var/www/html/wp-settings.php:512]
| #7 require_once(/var/www/html/wp-settings.php) called at [/var/www/html/wp-config.php:96]
| #8 require_once(/var/www/html/wp-config.php) called at [/var/www/html/wp-load.php:37]
| #9 require_once(/var/www/html/wp-load.php) called at [/var/www/html/wp-blog-header.php:13]
| #10 require(/var/www/html/wp-blog-header.php) called at [/var/www/html/index.php:17]
which is before the REST API has been initialised. It could be considered the expected behaviour since we only want this plugin to work for the actual API requests. Every authentication related check before the request has been parsed and routed to the REST controllers should be ignored.
The second time it gets called on the most basic WP install with just this plugin is during the REST API init:
#0 Application_Passwords::authenticate(, admin, ) called at [/var/www/html/wp-content/plugins/application-passwords/class.application-passwords.php:264]
#1 Application_Passwords::rest_api_auth_handler() called at [/var/www/html/wp-includes/class-wp-hook.php:286]
#2 WP_Hook->apply_filters(, Array ([0] => )) called at [/var/www/html/wp-includes/plugin.php:208]
#3 apply_filters(determine_current_user, ) called at [/var/www/html/wp-includes/user.php:2698]
#4 _wp_get_current_user() called at [/var/www/html/wp-includes/pluggable.php:69]
#5 wp_get_current_user() called at [/var/www/html/wp-includes/capabilities.php:640]
#6 current_user_can(unfiltered_html) called at [/var/www/html/wp-includes/functions.php:2872]
#7 get_allowed_mime_types() called at [/var/www/html/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php:766]
#8 WP_REST_Attachments_Controller->get_media_types() called at [/var/www/html/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php:684]
#9 WP_REST_Attachments_Controller->get_collection_params() called at [/var/www/html/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php:68]
#10 WP_REST_Posts_Controller->register_routes() called at [/var/www/html/wp-includes/rest-api.php:205]
#11 create_initial_rest_routes(WP_REST_Server Object ([*namespaces] => Array ([oembed/1.0] => Array ([/oembed/1.0] => 1,[/oembed/1.0/embed] => 1,...
#12 WP_Hook->apply_filters(, Array ([0] => WP_REST_Server Object ([*namespaces] ...
#13 WP_Hook->do_action(Array ([0] => WP_REST_Server Object ([*namespaces] => ...
#14 do_action(rest_api_init, WP_REST_Server Object ([*namespaces] => Array ([oembed/1.0] =>
#15 rest_get_server() called at [/var/www/html/wp-includes/rest-api.php:302]
#16 rest_api_loaded(WP Object ([public_query_vars] => Array ([0] => m,[1] => p,
#17 WP_Hook->apply_filters(, Array ([0] => WP Object ([public_query_vars] => Array
#18 WP_Hook->do_action(Array ([0] => WP Object ([public_query_vars] => Array ([0] =>
#19 do_action_ref_array(parse_request, Array ([0] => WP Object ([public_query_vars] =>
#20 WP->parse_request() called at [/var/www/html/wp-includes/class-wp.php:737]
#21 WP->main() called at [/var/www/html/wp-includes/functions.php:1105]
#22 wp() called at [/var/www/html/wp-blog-header.php:16]
#23 require(/var/www/html/wp-blog-header.php) called at [/var/www/html/index.php:17]
So any authentication checks for the actual REST requests should work as expected.
What do you think?
@kasparsd heres the server info. It seems to be Apache
@shockthealien Could you please post a detailed description of your issue -- what API endpoint are you trying to access, what is the exact request URL and the request headers?
I followed your instructions to fix the issue and added the code to the .htaccess file but I am still getting the error. Are there any other things that could be causing this?
When are you getting this error? Where is it being returned? How can I replicate it with a basic install of WP and this plugin?
@kasparsd I'll try but I am not hugely technical.
Basically I am trying to use the Distributor plugin from 10up (https://distributorplugin.com), and they require this plugin to be installed to work. (or to create a WP application)
They are trying to reach the http://yourdomain.com/wp-json
I tried a normal installation on the sites I was going working on and got the error, so I did a clean install of WordPress, updated to latest version and installed AP first. But get the error straight away
I followed the instructions to try to fix it adding the code to the .htaccess file but didnt solve it.
then I did the hook above and still didnt solve it.
Is there anything else you need? Im not sure how to figure out API endpoint or headers, sorry
Thanks for the explanation @shockthealien!
The warning is set if the web server fails this check HTTP Basic Auth check:
application-passwords/application-passwords.js
Lines 17 to 40 in 18d65df
You should reach out to your web hosting support about this. PHP needs access to $_SERVER['PHP_AUTH_USER']
and $_SERVER['PHP_AUTH_PW']
during HTTP requests with Basic Auth headers.
application-passwords/class.application-passwords.php
Lines 277 to 293 in aaa502d
Note that we try to support different server configurations but it appears that it also isn't working in this case:
application-passwords/class.application-passwords.php
Lines 295 to 329 in aaa502d
Thanks. I will try to get them to resolve that. Tho im not confident they will. Fingers crossed
@kasparsd I am out of ideas. I can confirm that with a basic WordPress installation (WordPress 5.2.6, Application Passwords 0.1.1), the required headers are filled but the following code fails:
add_action('rest_api_init', function () {
register_rest_route('download-monitor-release-version/v1', '/downloads/(?P<id>\d+)/release', array(
'methods' => 'POST',
'callback' => 'dlm_release_version_rest_callback',
'permission_callback' => function () {
$can_manage = current_user_can('read');
return $can_manage;
},
));
}
Permissions for permission_callback are valid and did work until Q4/2019.
@schakko yeah as I suspected the hosting company didn't know how to fix that, so I guess I am screwed and with nowhere to go
I'm getting the same error message as well even after following the wiki and modifying the .htaccess file. I'm using bitnami on ec2
I tried printing out the server variables you posted @kasparsd
<?php
echo $_SERVER['PHP_AUTH_USER'];
echo $_SERVER['PHP_AUTH_PW'];
?>
but i don't think they're set:
PHP Notice: Undefined index: PHP_AUTH_USER in /home/bitnami/test.php on line 2
PHP Notice: Undefined index: PHP_AUTH_PW in /home/bitnami/test.php on line 3
Any idea where to go from here?
Ah found the solution, I'll leave this here in case anyone else faces this issue with bitnami: https://community.bitnami.com/t/problem-getting-the-wordpress-rest-api-with-jwt-authentication-working-on-bitnamis-amazon-lightsail-wordpress/54214