[keycloak-user] How to implement access to resources based on resource roles
Pedro Igor Silva
psilva at redhat.com
Tue Apr 23 15:03:26 EDT 2019
When doing context-based authorization you need to provide all the
information you need in order to make the correct decisions. I would not
say you are bringing logic to your app but the opposite, where you are just
passing the facts that you need to be processed by your rules/policies.
IMO, what you are doing is fine. Just keep in mind that you might
eventually have some information/claim within the token already.
Regarding the entitlement request, I think you are not getting the
permissions because now your policies are based on certain claims ?
On Mon, Apr 22, 2019 at 1:06 PM Alfonso Alba García <alfonso at alfonsoalba.com>
wrote:
> 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