Authorization/Permissions with Thruway

You can use the AuthorizationManager that comes with Thruway to limit access to users of your Thruway Web Application Messaging Protocol (WAMP) router based on their roles.

In order to use authorization, you must setup a router that is able to authenticate. You can check out how to setup a JWT authenticating router here. I will be building on top of that example.

Please note that I will be referring to authorization and authentication in this post which look and sound pretty similar, but are not the same. Authentication is what verifies that a user is who they say they are. Authorization tells what that authenticated user is permitted to do.

In the JWT example, we don’t setup any authroles. By default, Thruway adds the role “authenticated_user” to every authenticated user. Let’s go a bit further and make it so that we can add an authroles array to the JWT token. This will give wherever you are generating your tokens to ability to grant roles to the users as well.

To generate tokens:

<?php

require_once __DIR__ . '/vendor/autoload.php';

$authid = "joe";
$key = "example_key"; // CHANGE THIS

$token = array(
    "authid" => $authid,
    "authroles" => ["user", "sales"]
);

$jwt = \Firebase\JWT\JWT::encode($token, $key);

echo $jwt;

The above token that is generated is “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoaWQiOiJqb2UiLCJhdXRocm9sZXMiOlsidXNlciIsInNhbGVzIl19.nuPY9SAhN86mZ3NFQhPuK2fRRw6ffLYOVUxwFBYqiDM”.

If we return the authroles from the processAuthenticate method in JwtAuthenticationProvider.php (we made this file in the JWT example post), Thruway will add those to the user. To do this, your processAuthenticate method should look like this now:

    public function processAuthenticate($signature, $extra = null)
    {
        $jwt = \Firebase\JWT\JWT::decode($signature, $this->jwtKey, ['HS256']);

        if (isset($jwt->authid)) {
            $detailsArray = ["authid" => $jwt->authid];
            if (isset($jwt->authroles) && is_array($jwt->authroles)) {
                $detailsArray["authroles"] = $jwt->authroles;
            }
            return ["SUCCESS", $detailsArray];
        } else {
            return ["FAILURE"];
        }
    }

The only difference is that now we are adding the authroles if they exist in the JWT token.

AuthorizationManager

Each realm can have an independent authorizer. We will setup our realm1 from the previous post to use the AuthorizationManager that Thruway comes with. This will allow us to limit what the user can do based on their role.

For more information on the AuthorizationManager, see here.

Setting up the realm with the AuthorizationManager can be done by adding this prior to adding the InternalClient:

$authorizationManager = new \Thruway\Authentication\AuthorizationManager('realm1');
$router->registerModule($authorizationManager);

You can setup some rules at router startup if you would like also:

// don't allow anything by default
$authorizationManager->flushAuthorizationRules(false);

// allow sessions in the sales role to subscribe to sales.numbers
$salesRule = new stdClass();
$salesRule->role   = "sales";
$salesRule->action = "subscribe";
$salesRule->uri    = "sales.numbers";
$salesRule->allow  = true;

$authorizationManager->addAuthorizationRule([$salesRule]);

// allow sessions in the bookkeeping role to publish to sales.numbers
$bookkeepingRule = new stdClass();
$bookkeepingRule->role   = "sales";
$bookkeepingRule->action = "publish";
$bookkeepingRule->uri    = "sales.numbers";
$bookkeepingRule->allow  = true;

$authorizationManager->addAuthorizationRule([$bookkeepingRule]);

Notice that the rule (the object with role, action, uri, and allow) is wrapped in an array in the call to addAuthorizationRule. This is because the addAuthorizationRule is the same procedure that is exposed via the RPC uri “add_authorization_rule”.

You should now have a working “realm1” realm with authorization rules.

The rules can be further refined by using the RPCs (from a session logged in from a trusted transport provider, or from a session with the role “admin”):

– add_authorization_rule
– remove_authorization_rule
– flush_authorization_rules
– get_authorization_rules
– test_authorization

Here is a plunkr with an example browser client.

This example can be found on github.

Leave a Reply