OAuth2Adapter uses the token's 'user_id' as AuthenticatedIdentity's name property

I’m not sure if the problem described below is a bug or not, so would like to hear some thoughts before creating an issue on github repository page.

In my app I use following dependencies:

I want to upgrade laminas/laminas-permissions-rbac to version 3 in order to make my app PHP 8 ready.

The problem
The laminas-permissions-rbac version 3.0.0 reorganized classes structure and added ‘string’ return type to Laminas\Permissions\Rbac\Role::getName().
The Laminas\Permissions\Rbac\Role is used as parent class for Laminas\ApiTools\MvcAuth\Identity\AuthenticatedIdentity. The setName() function of AuthenticatedIdentity doesn’t have type declared for $name parameter thus anything can be passed as argument. However if non string argument passed then AuthenticatedIdentity::getName() will throw a TypeError.

Now let’s look inside Laminas\ApiTools\MvcAuth\Authentication\OAuth2Adapter::authenticate()

        $token = $this->oauth2Server->getAccessTokenData($oauth2request);

        // Failure to validate
        if (! $token) {
            return $this->processInvalidToken($response);

        $identity = new Identity\AuthenticatedIdentity($token);

It will set name to what ever $token[‘user_id’] is. Now let’s move to the bshaffer/oauth2-server-php pacakge.
The OAuth2\Server::getAccessTokenData() will return the value of OAuth2\Controller\ResourceController::getAccessTokenData() function which will return the value of OAuth2\Storage\AccessTokenInterface::getAccessToken().

     * Look up the supplied oauth_token from storage.
     * We need to retrieve access token data as we create and verify tokens.
     * @param string $oauth_token - oauth_token to be check with.
     * @return array|null - An associative array as below, and return NULL if the supplied oauth_token is invalid:
     * @code
     *     array(
     *         'expires'   => $expires,   // Stored expiration in unix timestamp.
     *         'client_id' => $client_id, // (optional) Stored client identifier.
     *         'user_id'   => $user_id,   // (optional) Stored user identifier.
     *         'scope'     => $scope,     // (optional) Stored scope values in space-separated string.
     *         'id_token'  => $id_token   // (optional) Stored id_token (if "use_openid_connect" is true).
     *     );
     * @endcode
     * @ingroup oauth2_section_7
    public function getAccessToken($oauth_token);

The returned array must have this structure but it doesn’t force the user_id to be a string. What makes sense, because if you use MySQL then highly likely you will use integer ids for your users and if you use MongoDB then you will use strings (ObjectId) as ids for users.

I hope I described the problem clear enough.