Currently we have user.hasRole(String)
and user.hasPermission(String)
even though the separation of roles
and permissions
sounds logic there are some deficiencies with the current implementation.
The first false assumption is that roles and permissions are independent and relate to a user. So say that user Paulo
has role dev
and permission push
. Now lets assume the whole application knows about the roles dev
and devops
and a dev
role can push
code and a devops
role can push
releases into production.
Now with our model if we want to assert if Paulo
can push
to production we need to do:
paulo.hasRole("devops") && paulo.hasPermission("push")
The logic here would fail since false
&& true
is false
. Now just say that because I am the lead developer i might have read
access to prod to pull logs or something... so now Paulo
is a dev
with push
permissions and devops
with read
permissions.
The same check from above will assert true
even tough it is not correct. The hasPermission
has no context about from which role
to check the permission for.
How can we fix this:
We need to refactor the User
to have a method hasAuthority(String)
if we like the Spring style or isPermitted(String)
if we like the Shiro style. After reading both I am tending for Shiro...
Now the assertion is a String, both Spring and Shiro have conventions about the format of the Strings. Looking at Shiro a authority has the format:
<role or domain>[:<action>[:<instance>]]
examples would be:
printers:print:color_printer_1st_floor
devops:read
dev:push
The impact is that using this approach we can have the same model fitting all current implementations:
The Strings are opaque so they only have specific meaning to the implementations and no assumptions on the format is made by vertx-auth
, the usage of the format above is just an example and if one prefers can use String notation:
Role_devops
Role_dev
devops:push
devops:read
dev:push
Since the assumption is that the String are opaque it is to the implementation of auth
providers to define if they support or not wildcards, e.g.: printers:print:*
.