Scope and FOSOAuthServerBundle


In this video we are taking a look at Scope in the context of a FOSOAuthServerBundle installation.

In my opinion, the main thing to understand when dealing with Scope in FOSOAuthServerBundle is that the Scope is assigned to your Token, not to the underlying User (if there is one).

If you rely solely on whether the Scope value that a User provides to determine if that User really has the right permissions to be carrying out some task, then you're gunna have a bad time.

How to implement Scope isn't specified in any great detail in the RFC. But, essentially, you can think of Scope as being a form of permission.

When someone requests a Token, they will also tell you what Scope (or permission(s)) they want.

In the concept of Symfony 2, this is the equivalent of a User telling you what Roles they should have.

However, the confusing part is that the requested Roles are not given directly to the User, but rather to the AccessToken that represents that User.

An Example With Robots

Let's assume we have a User on our system called Rupert.

We have some scopes defined:

# app/config/config.yml
fos_oauth_server:
    service:
        options:
            supported_scopes: read update delete

This implies we have at least three Symfony Roles configured in our configuration:

  • ROLE_READ
  • ROLE_UPDATE
  • ROLE_DELETE

Rupert is a new starter and shouldn't be able to delete things, but he needs to be productive, so he is allowed to both read and update whatever it is that Rupert's new employer actually does.

Rupert's employer are a paranoid bunch, and have locked down the amount of access the application used by Rupert and the other employees in Sector 7B can actually request. As such, Rupert's application is hard-wired to only ever request read and update.

As part of a top secret corporate espionage programme, Rupert is abducted and replaced with the 'Rupert Robot Replacemotron 9000'. His mission is simple: corporate sabotage.

Equipped with new hacker skills, the Replacemotron 9000 quickly deduces that if it sends in a request for a Token, but leaves off the scope, the server rather strangely gives the AccessToken it returns all Scopes configured in the system.

Free to reign terror, the Replacemotron can now happily send in requests to delete - as the AccessToken has that Scope (or ROLE_DELETE role).

Repelling the Robot

So, obviously, we don't want a situation where a person can bump up their access level by simply telling us they should be at that level.

We want them to be able to tell us, but we shouldn't trust their request until we verify it against our systems internal knowledge.

This is not helped by how the Token will be checked against any configured ACL, rather than our underlying User. As such, we must double check / can't rely solely on the Symfony ACL / security.yml file.

There are many solutions to this problem, and the one detailed in the video is likely amongst the most simplistic and basic. We make use of the Security Component improvements from Symfony 2.6 to check if our underlying User object should have permissions in the Controller action itself.

Further Examples and Reading

Whilst not related to FOS OAuth Server Bundle, there some nice examples of using Scope in the docs for The League of Extraordinary Packages's OAuth 2 Server by Alex Bilbie.

Likewise the OAuth 2.0 Server PHP docs also cover an alternative implementation but are good for referencing.

And of course, the RFC.

Code For This Course

Get the code for this course.

Episodes