Oauth2-server: Access authCodePayload in AccessTokenRepository or RefreshTokenRepository?

Created on 11 Sep 2018  路  9Comments  路  Source: thephpleague/oauth2-server

Hi, when I'm creating an authCode and thus using the persistNewAuthCode method I also save another piece of information in a column named accountId because users can access various accounts with the same login information in my app.

I'm currently facing a challenge when getting a new access token with the authCode I receive because I cannot access the authCodePayload when the access token or refresh token is persisted to the database and thus I cannot access the accountId stored within it.

Is this something that is possible? If so how, if not, what is a better way for approaching this?

Question

All 9 comments

Hi @nealoke - it depends what you are using the accountId field for but usually, scopes would be used to restrict the capabilities of an auth code and eventually issued access token. Have you looked at these as a potential solution?

@Sephster Thanks for the quick reply. As a matter of fact I thought about it but because the auth codes are used for integrations that are for a specific accountId it seems a bit weird to use the actual user as resource owner and block the access with a scope.

Do you think it is appropriate to use the accountId as the resource owner in stead of the user? Or is this not a good practice for Oauth?

To be honest, it really does depend on your implementation although typically, it will be a user who owns the resource and is granting access to a third party client.

I still think scopes are probably the way to go here but it is hard for me to comment here as I don't have a full grasp of what you are trying to achieve. OAuth is simply a way of granting access to a user's protected resources.

It sounds like you have achieved the granting part but you want to restrict what level of access is provided and _not_ allow the third party client to have complete access to the users resources. Scopes are usually used to achieve this.

For example, a Twitter client might have access to read tweets but not post them as per the scopes provided. In your implementation, the third party client should probably be defining which accounts it is trying to access using the user's access through scopes.

I can't think of any other way of doing this to be honest. I'm sorry that isn't a massive help as you'd stated you don't want to use scopes but it seems appropriate for this implementation.

@Sephster the problem is that my knowledge on how to setup integrations with oauth is very limited and I'm sure you have a better understanding and knowledge about this.

But what if the user who setup the integration get's deleted? The integration (because the accessToken and refreshToken are scoped on the user) also becomes invalid then I guess?

So for example user "John" is created in the account. He wants to setup an integration the company's application and a third party one and thus starts the auth grand flow. After successfully granting the scopes etc. the integration is working. Now user "John" gets fired and his account is deleted. The integration which is still using the scoped accessToken(s) and refreshToken is now invalid and thus the integration is not working anymore. Doens't this seems like highly odd?

My situation is not so much requesting resources of a user but more requesting / modifying resources of an account. You can compare it with a Trello powerup, are these also linked to the user or to the team?

The purpose of the Auth Grant is to allow third parties to have access to a user's resources without sharing the user's credentials with the third party. Presumably your auth code grant will go something like this:

  • The client directs the users to the login page of your protected resource and specifies which scopes it wants access to (if applicable)
  • The user reviews the access request, and enters his/her login details if they are happy
  • An authorisation check takes place and if all is ok, we redirect back to the client with an auth code

In this scenario, it is the user who is authorising that the auth token and eventual access token be created. If that user no longer has access to the resource server, their tokens will usually be deleted although this will depend on your own policy (this is outside the scope of both this server and the OAuth spec).

My situation is not so much requesting resources of a user but more requesting / modifying resources of an account. You can compare it with a Trello powerup, are these also linked to the user or to the team?

Given the above, if you don't want to request the resources of a user, how can you use the auth grant? Who is reviewing the auth code request on behalf of the account? Which credentials will you use to login and authenticate with the resource server authentication end point? How are you going to confirm who gave access to that account?

I am guessing that if we take OAuth out of the equation, it will be a user that will normally manipulate an accounts information in your system, so it makes sense to me that it is a user that is associated with an auth/access token as they will be giving the third party client permissions to perform many of the actions they can do. If you want to limit these actions, you do so using scopes.

I hope that helps in some manner to explain why I think it is not right to focus on accounts but again, having not seen your application, I might be making some false assumptions.

Just thinking of it here is a question which might help clarify matters:

How do you determine which account ID is associated with a given auth code at the moment?

@Sephster This cleared up quite a bit 馃憤 . I'm gonna try now to implement it with the scope based approach and see if I run in any issues when I do this. Thanks for the time and effort to put forth such an explanation!

Trying to do the scope based approach I have a few questions namely

Why is the scope not stored at the refresh token level as well?

How do you actually add a scope like accountId = 1?

How come the outcome is not a json format for the code below?

    public function finalizeScopes(
        array $scopes,
        $grantType,
        ClientEntityInterface $clientEntity,
        $userIdentifier = null
    ) {
        // Example of programatically modifying the final scope of the access token
        $scope = new ScopeEntity();
        $scope->setIdentifier('email');
        $scopes[] = $scope;

        return $scopes;
    }

Outcome $accessTokenEntity->getScopes() is a:1:{i:0;O:26:"Entities\ScopeEntity":1:{s:13:"*identifier";s:5:"email";}}?

  • The access token is stored within the refresh token so as long as you have scopes associated with the access token, they will also be associated with the refresh token.
  • Typically your scopes will be issued by the client as part of the initial authorisation request. These usually aren't key value pairs, and instead are single strings. In your instance, you might have a scope called account1 or something similar.
  • I'm not sure about your last point. The function getScopes() should return an array of ScopeEntityInterfaces. I would use the print_r() function to perhaps check the output to make sure this is correct.

@Sephster thanks, I just implemented it with your comments from above and it works like a charm. I can't thank you enough 馃 !

Glad to be of help!

Was this page helpful?
0 / 5 - 0 ratings