[keycloak-user] How to implement access to resources based on resource roles

Alfonso Alba García alfonso at alfonsoalba.com
Mon Apr 22 12:06:39 EDT 2019


Hi,

I've been able to simplify the policy model a lot by posting claims to 
the resource server. Since I'm using rails and there is no adapter and 
no policy enforcer implementation, I'm just making calls to the REST API 
and sending the claims with the context that I need.

Instead of create a resource for each new entity that the user creates, 
in our resource server we create just one resource for each resource 
type, for example:

     {
       "name": "Event Resource",
       "type": "Event",
       "ownerManagedAccess": false,
       "displayName": "Event Resource",
       "attributes": {},
       "_id": "XXXXXXX",
       "uris": [
         "http://localhost:3000/events/*
       ],
       "scopes": [
         {
           "name": "event:create"
         },
         {
           "name": "event:edit"
         },
         {
           "name": "event:show"
         },
         {
           "name": "event:destroy"
         }
       ]
     }


     {
       "name": "Meeting Resource",
       "type": "Meeting",
       "ownerManagedAccess": false,
       "displayName": "Meeting Resource",
       "attributes": {},
       "_id": "XXXXXXX",
       "uris": [
         "http://localhost:3000/meetings/*
       ],
       "scopes": [
         {
           "name": "meeting:create"
         },
         {
           "name": "meeting:edit"
         },
         {
           "name": "meeting:show"
         },
         {
           "name": "meeting:destroy"
         }
       ]
     }

I created one Rule-based policy in javascript that reads all the claims 
passed by our app in the API call and then decides if the user has 
access to a particular instance of the resource.

Doing this I managed to simplify the policy model substantially. On the 
other hand, we have to pass to the resource server all the context 
(around 15 claims) needed by the policy to know it the user can access a 
resource. I'm wondering if this Ok or I'm putting too much logic in the 
application side that should be in keycloak.

Furthermore, with this policy model I when I get the entitlements for a 
user, the token that we get does not contain a list of resources to 
which the user has access. This means we would need to query the 
resource server individually for any resource the user wants to access.

I'm quite new to keycloak and UMA. Before, all this logic was 
implemented in our application and I'm trying to figure out who should 
do what. Since we have a lot of rules, I have the feeling that the 
application should provide the context (claims) and keycloak should 
implement the rules to grant access to the resources based on that 
context. Am I seeing this right?

Thanks again for your help.

Alfonso.



Pedro Igor Silva wrote:
> Hi,
>
> Some comments inline ...
>
> On Wed, Apr 17, 2019 at 2:16 PM Alfonso Alba García
> <alfonso at alfonsoalba.com <mailto:alfonso at alfonsoalba.com>> wrote:
>
>     I've installed keycloak locally and now I'm trying to implement these
>     requirements. I've started with the ones I think are the easiest: The
>     organisation Owner an Administrator. Following what's suggested in the
>     threads mentioned above, I implemented these resource roles as follows:
>
>     * Create three scopes: organisation:edit, organisation:view,
>     organisation:billing
>
>     * Create a resource "Organisation 1" with scopes organisation:edit,
>     organisation:view and organisation:billing
>
>     * Create two client roles "Organisation 1 Owner" and "Organisation 1
>     Administrator"
>
>     * Create two policies: "Organisation 1 Owner Policy" and
>     "Organisation 1
>     Administrator Policy"
>
>     * Create one scope-permission "Organisation 1 Managers Permissions"
>     that
>     allows users with roles "Organisation 1 Owner" or "Organisation 1
>     Administrator" get permission for the scopes organisation:edit and
>     organisation:view
>
>     * Create one scope-permission "Organisation 1 Owners Permissions" that
>     allows users with roles "Organisation 1 Owner" access the scope
>     organisation:billing
>
>
> Your policy model is fine but I think you can make it simpler if you
> just use groups to represent organization membership.
>
> By using groups, you can have a single "Organization Resource",
> "Organization Managers Permissions" and "Organization Owner Permission".
> Your policies could benefit from claims pushed by your application [1]
> in order to make decisions based on whether or not the user is a member
> of an organization plus the RBAC.
>
> For instance, if you have in Keycloak a group "organization-foo" and
> your application provides a REST endpoint like "/api/organizations/foo",
> you could send the request URI to your policies, extract the "foo" part
> of it and check if the user is member of organization-foo. I think the
> same logic could be applied to other resource types.
>
> You could check this example [2].
>
> [1]
> https://www.keycloak.org/docs/latest/authorization_services/index.html#_enforcer_claim_information_point
> [2]
> https://github.com/keycloak/keycloak-quickstarts/tree/latest/app-authz-rest-employee
>
>     I created these for three organisations and as well as several users.
>     I've been playing around with them using the Evaluate functionality of
>     the keycloak client and apparently everything is working fine. Now I'm
>     thinking about how I could implement the access to the packages I
>     mentioned above, the members, etc, but before I continue I have several
>     questions:
>
>     * Since users can have different roles in different organisations, I'm
>     creating only one realm. I guess that's ok since different realms do
>     not
>     share users.
>
>     * For every organisation that we create in our application we will need
>     to create all the policies, roles and permissions described above. Is
>     this supposed to be like that or am I missing something?
>
>     * If this is the way to do it, I was wondering if it's a good idea to
>     create a Resource Server (i.e. a new client inside the realm) for each
>     organisation. This way I can create a client organisation-1-client with
>     all the resources, policies and permissions for "Organisation 1". I
>     think that this will make deleting an organisation quite easy after the
>     user deletes the organisation, I just need to delete de client
>     organisation-1-client. I don't know if this a good idea or not, has it
>     any negative impact in performance? will this make the application code
>     more difficult? or may be this not a good practice for any reason?
>
>
> I would recommend you to try other approaches like that one I suggested.
> I can think about another one using resource types.
>
> Considering your current design, I think the addition of a new
> organization is pretty much related to a provisioning logic backed by
> our REST APIs, so you can automatize this process. But I hope you can
> find an alternative ...
>
>
>     Thanks for your time. Regards,
>
>     Alfonso
>
>
>     -------
>     [1]
>     http://lists.jboss.org/pipermail/keycloak-user/2016-August/007309.html
>     [2] http://lists.jboss.org/pipermail/keycloak-user/2018-June/014347.html
>     _______________________________________________
>     keycloak-user mailing list
>     keycloak-user at lists.jboss.org <mailto:keycloak-user at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/keycloak-user
>


More information about the keycloak-user mailing list