Summary
I was trying the Oauth2 authentication with Oro and it worked well localy, but when I tried in a production environment it started to throw errors like this:
League\OAuth2\Server\Exception\OAuthServerException
The resource owner or authorization server denied the request.
So after several tests I realize that the difference between environments is that in production we have a "master" database and a "slave" database for replication. So the problem was that I the access token is generated succesfuly, but when the system tries to use the generated token it fails, because Oro is trying to match the token with the "Slave DB", and the replication in the DB takes a few seconds, so it doesn't find the token and throws the error.
Steps to reproduce
Is needed to have a crm-application with "master/slave" configuration in the doctrine section of the config.yml, something like this:
Have an external system that generates an Access Token for Oro through the /oauth2-token oro Endpoint.
Use the token in another Oro endpoint with the 'Authorization' => 'Bearer ' . $accessToken
Actual Result
The system will throw an error:
The resource owner or authorization server denied the request.
Expected Result
There should be no errors in a request with a new access token.
Proposed solution
I fixed in my system overriding the Class vendor/oro/oauth2-server/src/Oro/Bundle/OAuth2ServerBundle/League/Repository/AccessTokenRepository.php and forcing to use master DB when it tries to get the access tokens, like this:
public function findAccessTokenEntity($tokenId): ?AccessToken
{
// To get always the token from the master db and avoid the delay of slave replication
$this->getEntityManager()->getConnection()->connect('master');
return $this->getEntityManager()->getRepository(AccessToken::class)
->findOneBy(['identifier' => $tokenId]);
}
I think that solution could be easily implemented on Oro's side, since it makes sense to always have consistency for recently created tokens.
Summary
I was trying the Oauth2 authentication with Oro and it worked well localy, but when I tried in a production environment it started to throw errors like this:
So after several tests I realize that the difference between environments is that in production we have a "master" database and a "slave" database for replication. So the problem was that I the access token is generated succesfuly, but when the system tries to use the generated token it fails, because Oro is trying to match the token with the "Slave DB", and the replication in the DB takes a few seconds, so it doesn't find the token and throws the error.
Steps to reproduce
Is needed to have a crm-application with "master/slave" configuration in the doctrine section of the config.yml, something like this:
Have an external system that generates an Access Token for Oro through the
/oauth2-token
oro Endpoint.Use the token in another Oro endpoint with the
'Authorization' => 'Bearer ' . $accessToken
Actual Result The system will throw an error:
Expected Result
There should be no errors in a request with a new access token.
Proposed solution I fixed in my system overriding the Class
vendor/oro/oauth2-server/src/Oro/Bundle/OAuth2ServerBundle/League/Repository/AccessTokenRepository.php
and forcing to usemaster
DB when it tries to get the access tokens, like this:I think that solution could be easily implemented on Oro's side, since it makes sense to always have consistency for recently created tokens.
Details about your environment