0

When using OAuth2 Server module to authorize with users, I am not receiving the correct "sub" parameter in the response from the server. I get all the other fields such as email, email_verified, name, preferred_username, and zoneinfo; just not the sub parameter.

{
  "sub": null,
  "email": "[email protected]",
  "email_verified": true,
  "name": "SomeUser",
  "preferred_username": "SomeUser",
  "zoneinfo": "Asia/Dubai"
}

I've tried using hook_oauth2_server_user_claims to alter this parameter like so:

function my_module_oauth_server_user_claims($account, $requested_scopes) {
  $claims = [];

  if (in_array('profile', $requested_scopes)) {
    $claims['sub'] = $account->id();
    $claims['user_id'] = $account->id(); // for debugging purposes
  }

  return $claims;
} 

Doing this adds the user_id parameter to the response body, but the 'sub' is still set as 'null', therefore it must get override afterwards.

I double checked the documentation and have all the permissions set, but can't find anything about this particular issue.. Why is `sub' not being populated correctly during this process?

0

1 Answer 1

0

The code invoking that hook is the following one, in the OAuth2Storage.php file, line 750 and forward.

    // Prepare the default claims.
    $claims = [
      'sub' => $account->{$sub_property}->value,
    ];

    if (in_array('email', $requested_scopes)) {
      $claims['email'] = $account->getEmail();
      $claims['email_verified'] = $this->configFactory->get('user.settings')
        ->get('verify_mail');
    }

    if (in_array('profile', $requested_scopes)) {
      if (!empty($account->label())) {
        $claims['name'] = $account->getDisplayName();
        $claims['preferred_username'] = $account->getAccountName();
      }
      if (!empty($account->timezone)) {
        $claims['zoneinfo'] = $account->getTimeZone();
      }
      $anonymous_user = new AnonymousUserSession();
      if ($anonymous_user->hasPermission('access user profiles')) {
        $claims['profile'] = $account->toUrl('canonical', ['absolute' => TRUE]);
      }
      if ($picture = $this->getUserPicture($account)) {
        $claims['picture'] = $picture;
      }
    }

    // Allow modules to supply additional claims.
    $claims += $this->moduleHandler->invokeAll('oauth2_server_user_claims', [
      'account' => $account,
      'requested_scopes' => $requested_scopes,
    ]);

    // Finally, allow modules to alter claims.
    $context = [
      'claims' => &$claims,
      'account' => $account,
      'requested_scopes' => $requested_scopes,
    ];
    $this->moduleHandler->alter('oauth2_server_user_claims', $context);
    return $claims;

Since the code first sets $claims to ['sub' => $account->{$sub_property}->value] and then adds any array key returned from that hook with $claims += $this->moduleHandler->invokeAll('oauth2_server_user_claims', ['account' => $account, 'requested_scopes' => $requested_scopes]); the hook cannot change the value for the sub key. You can verify how PHP behaves with the following simpler code.

$array = ['sub' => NULL];
$array += ['sub' => 10, 'id' => 10];
print_r($array);

To alter the sub key, the module should implement hook_oauth2_server_user_claims_alter().

function my_module_oauth_server_user_claims_alter(&$context) {
  if (in_array('profile', $context['requested_scopes'])) {
    $context['claims']['sub'] = $account->id();
    $context['claims']['user_id'] = $account->id();
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.