First, authentication.
That's just logging in and asserting that username / password combinations are related to user X.
Second, authorization.
The second is generally where things can get more complex. But for most use cases your general understanding is fine.
Packages like Zend\Rbac or Zend\Acl are good starting points for implementing authorization in your domain logic. I prefer RBAC because there are more involved implementations of it. Read up on that for more nuanced approaches.
With rbac a user has a role (admin) which can inherit from moderator which can also inherit from user. In rbac the role is authorized to do something, not the identity (user / principal in other languages). Where things can get tricky when you authorize editing of comments. Only the owner can edit his or her own comments (per-entity rules). But the moderator can edit or delete anyone's comments.
In the package above, I use a custom-written assertion for the per-entity authorizations as that's a very simple way to handle that in that package. Or you could have a user that is an admin of customer X … but that doesn't mean they are an admin of customer Y. So your rules can get pretty involved beyond just a simple hierarchy.
In those cases, each user would probably have a many to many relationship with customers and the associated roles for each one.
Your isAllowed method would have to check based on the business criteria for that. And that's specific to your domain - which is why authorization strategies vary quite a bit from project to project. Generally that happens when things get complex. Otherwise, most of the time permissions really aren't too complex to figure out.