Refresh session data / identity object

Please, i need help.

When I log in to my application, the user information and permissions are stored in the session’s authentication object.
My User Entity implements the IdentityInterface.

However, if the user itself or an administrator changes the information in the database, this object should be updated in the session.

As a temporary measure, I ran the following command while editing in UserController:

public function edit($id=null) {
...
   $this->refreshSessionData();
...
}

    private function refreshSessionData()
    {
        $user = $this->Users->get($this->Authentication->getIdentity()->get('id'), ['finder' => 'authenticatedUser']);
        $this->Authentication->setIdentity($user);
    }

However, I now had the problem that this only applied to one session, so if I was logged in in another browser with the same user, that data in session was not updated.

Now my approach is to fetch the user data from the database with every request and update the session. I wanted to do this via the AppController::beforeFilter(), but it doesn’t seem to work.

public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);

$user = $this->fetchTable('Users')->get($this->Authentication->getIdentity()->get('id'), ['finder' => 'authenticatedUser']);
$this->Authentication->setIdentity($user);
}

I get the following error message.

Call to undefined method App\Model\Entity\User::can()
in RequestAuthorizationMiddleware…

Okay maybe i found the problem. It wasn’t the RequestAuthorizationMiddleware. The Error occurs in view:

            if ($this->Identity->isLoggedIn() && $this->request->getAttribute('identity')->can('view', new User())) {
                echo $this->Html->link('Benutzer', '/users');
            }

Maybe that’s not best practice, but how can i get Authorization informations in view for navigation links?

It doesn’t seem to be that easy to keep the session data up to date.

The Authentication Component’s setIdentity() method doesn’t seem to do what it’s supposed to do, even though it’s described here:

https://book.cakephp.org/authentication/3/en/migration-from-the-authcomponent.html#checking-identities

In this code snipet from docs you can read the entity from database and set it as identity, but it’s not working…

Here is a working code, although it’s not really nice to do it this way:

public function beforeFilter(EventInterface $event)
{
        parent::beforeFilter($event);

        if ($this->Authentication->getIdentity()) {
            $user = $this->fetchTable('Users')->get($this->Authentication->getIdentity()->get('id'), 
                ['finder' => 'authenticatedUser']);
            $session = $this->request->getSession();
            $session->write('Auth', $user);
        }
}

Any other solution to solve that problem?

If you use the SessionAuthenticator then

$this->Authentication->setIdentity($user);

should keep the session values up2date. You just need to call it whenever the User gets updated.

But if it’s somebody other than the user in question updating the user data (e.g. an admin), this won’t have any effect on the updated user’s session.

Sorry, i did this in AppController’s beforeFilter() method, but that didn’t work, because after that many other components or in view it’s expecting an Authorization/Identity type, but there was a Entity/User type and it couldn’t find the can() method.

Please see my first post.
In UsersController → refreshSessionData() the setIdentity() works well. When i move that to beforeFilter() in AppController it doesn’t work. Maybe because i redirect to another page after set the Identity in UsersController?