Problem/Motivation
This error message appears when there is an exception when user information is retrieved with access token and $userinfo is set to FALSE.
Trying to access array offset on value of type bool in Drupal\openid_connect\Form\OpenIDConnectSettingsForm->buildForm() (line 273 of modules/contrib/openid_connect/src/Form/OpenIDConnectSettingsForm.php).
Steps to reproduce
Variable $userinfo is FALSE.
Variable $user_data is not empty.
Variable $results is FALSE.
private function buildContext(OpenIDConnectClientInterface $client, array $tokens) {
$user_data = $client->decodeIdToken($tokens['id_token']);
$userinfo = $client->retrieveUserInfo($tokens['access_token']);
$provider = $client->getPluginId();
$context = [
'tokens' => $tokens,
'plugin_id' => $provider,
'user_data' => $user_data,
];
$this->moduleHandler->alter('openid_connect_userinfo', $userinfo, $context);
// Whether we have no usable user information.
if (empty($user_data) && empty($userinfo)) {
$this->logger->error('No user information provided by @provider (@code @error). Details: @details', ['@provider' => $provider]);
return FALSE;
}
if ($userinfo && empty($userinfo['email'])) {
$this->logger->error('No e-mail address provided by @provider (@code @error). Details: @details', ['@provider' => $provider]);
return FALSE;
}
$sub = $this->extractSub($user_data, $userinfo);
if (empty($sub)) {
$this->logger->error('No "sub" found from @provider (@code @error). Details: @details', ['@provider' => $provider]);
return FALSE;
}
/** @var \Drupal\user\UserInterface|bool $account */
$account = $this->authmap->userLoadBySub($sub, $provider);
$context = [
'tokens' => $tokens,
'plugin_id' => $provider,
'user_data' => $user_data,
'userinfo' => $userinfo,
'sub' => $sub,
'account' => $account,
];
$results = $this->moduleHandler->invokeAll('openid_connect_pre_authorize', [
$account,
$context,
]);
// Deny access if any module returns FALSE.
if (in_array(FALSE, $results, TRUE)) {
$this->logger->error('Login denied for @email via pre-authorize hook.', ['@email' => $userinfo['email']]);
return FALSE;
}
// If any module returns an account, set local $account to that.
foreach ($results as $result) {
if ($result instanceof UserInterface) {
$context['account'] = $result;
break;
}
}
return $context;
}
Code will try to log an error with $userinfo['email'] but $userinfo is FALSE so we will get a warning.
Proposed resolution
Change this part of code:
if ($userinfo && empty($userinfo['email'])) {
$this->logger->error('No e-mail address provided by @provider (@code @error). Details: @details', ['@provider' => $provider]);
return FALSE;
}By this one:
if (!$userinfo || empty($userinfo['email'])) {
$this->logger->error('No e-mail address provided by @provider (@code @error). Details: @details', ['@provider' => $provider]);
return FALSE;
}This way, when $userinfo is FALSE, the error message "No e-mail address provided..." will be displayed instead of continuing code execution.
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork openid_connect-3458320
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3458320-trying-to-access
compare
Comments
Comment #3
jcnventuraPHP uses short-circuit operators in && operators. The only way to get to the second operator is if the first one is evaluated to true. In this case, since the error is complaining about it being a boolean, it means that $userinfo is TRUE.
It is hard to understand what the origin of the problem is here, since the error is in line 273 of OpenIDConnectSettingsForm, specifically in the buildForm() method, but that method is defined in lines 123 to 272 (see https://git.drupalcode.org/project/openid_connect/-/blob/8.x-1.4/src/For...)
Can you please confirm the version of the module that you're running, and what patches you're applying to it?
Comment #4
j-leeSeems outdated to me, as the code base has changed.
Comment #5
steinmb commentedGoing out on limb here and closing as outdated.