[keycloak-dev] How to share a resource with a user via UMA 2.0 API

Pedro Igor Silva psilva at redhat.com
Fri May 11 12:04:06 EDT 2018


On Fri, May 11, 2018 at 10:19 AM, Federico Michele Facca <
federico.facca at martel-innovate.com> wrote:

> Hi Pedro,
>
> Thanks a lot for your quick reply.
>
> On 11 May 2018, at 13:52, Pedro Igor Silva <psilva at redhat.com> wrote:
>
>>
>>
> We don't have API documented, something we should improve in the future.
>
> We have a quickstart that can help you to achieve what you want. See
> https://github.com/keycloak/keycloak-quickstarts/
> tree/latest/app-authz-uma-photoz.
>
> If you look this method:
>
>     https://github.com/keycloak/keycloak-quickstarts/blob/
> latest/app-authz-uma-photoz/photoz-restful-api/src/main/
> java/org/keycloak/example/photoz/album/AlbumService.java#L100
>
>
> I have been looking at the methods, and actually learned from the exact
> example you refer to.
>
>
> You will see that we are using the Permission Endpoint (the endpoint
> responsible for managing permission tickets) to obtain all resources
> *shared* with a specific user. In our AuthZ Java Client we have this method:
>
>     https://github.com/keycloak/keycloak/blob/master/authz/
> client/src/main/java/org/keycloak/authorization/client/
> resource/PermissionResource.java#L162
>
> Which allows you to query for permission tickets using different filters.
>
>
> Maybe my examples were not clear enough. For question 2:
>
>
> Suppose that user "test" owns resource A and he want to see (like in the
> my account interface) a table with all the active and pending permissions
> including the identifier of the user that made the request.
>
> Shared resources->
>
> Resource A user B scope read, write
>
> Pending requests->
>
> Resource A user C scope read
>
>
> With the following query:
>
> curl --request GET \
>   --url 'http://127.0.0.1:8080/auth/realms/master/authz/
> protection/permission?returnNames=true&owner=test' \
>   --header 'authorization: Bearer xxx'
>
> I get a list of the permissions (where granted = true are the authorised
> ones and granted = false the pending ones):
>
> [
>     {
>         "id": "08dccaed-6dbb-47aa-a87c-55b35a6f2523",
>         "owner": "567c20ad-7d42-4908-bb53-af26c64534e7",
>         "resource": "218091a8-e5fc-460c-a306-a3a76775c784",
>         "scope": "65e40351-bce4-4e3f-825d-7bca9d78d12e",
>         "granted": true,
>         "scopeName": "read",
>         "resourceName": "8910"
>     },
>     {
>         "id": “xxxx",
>         "owner": "567c20ad-7d42-4908-bb53-af26c64534e7",
>         "resource": "218091a8-e5fc-460c-a306-a3a76775c784",
>         "scope": "65e40351-bce4-4e3f-825d-7bca9d78d12e",
>         "granted": false,
>         "scopeName": "read",
>         "resourceName": "8910"
>     }
> ]
>
> so the result does not allow me to know who was the “requester” (which I
> don’t know apriori since the query is about all potential requesters)
>

>
> so my idea was that when you use returnNames=true parameter you could add
> as well the requester, e.g.:
>
>     {
>         "id": "08dccaed-6dbb-47aa-a87c-55b35a6f2523",
>         "owner": "567c20ad-7d42-4908-bb53-af26c64534e7",
>         "resource": "218091a8-e5fc-460c-a306-a3a76775c784",
>         "scope": "65e40351-bce4-4e3f-825d-7bca9d78d12e",
>         "granted": true,
>         "scopeName": "read",
>         "resourceName": “8910”,
>         “requester”:”xxxxx”,
> “requesterName”:”test”
>     },
>

I see now. We are really missing *requester* in the response. Not sure why
it is not there already ....

Created https://issues.jboss.org/browse/KEYCLOAK-7337.


>
>
>
>
> The type PermissionResource also provides methods for CRUD permission
> tickets.
>
> Note that this API is targeted for resource servers and part of the
> Protection API.
>
>
>
> We realised that by trying to create resources and seeing that using user
> authentication you get 500 error while using client authentication it works
> (even though UMA specs is not limiting the access to that).
> We found out by testing also that the permission endpoint works also with
> user access tokens.
>

Yeah, as long as the access token is granted with uma_protection scope.


>
> Now the first question was how to “share” directly a resource with a user.
>
> Currently using the API, supposing I am user A and I want to access a
> resource Z from user B, we proceed as follow (i hope is the correct way…
> any correction or guidance will be appreciated):
>
> 1.  We create a permission request on the API (to get the ticket). E.g.
> read resource x
>
> 2.  We use the ticket to ask for a rtp token using a user token.
>
> curl --request POST \
>   --url http://127.0.0.1:8080/auth/realms/master/protocol/openid-
> connect/token \
>   --header 'Authorization: Bearer xxx' \
>   --header 'Content-Type: application/x-www-form-urlencoded' \
>   --data 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%
> 3Auma-ticket&ticket=xxxx'
>
> If the user has already access, then he gets the rtp, if not he gets:
>
> {
>     "error": "access_denied",
>     "error_description": "request_submitted"
> }
>
> Only in this moment the permission ticket i created at step 1 appears in
> the list of permissions. (I am not sure this is the intended behaviour
> though).
>

Yeah, that is the expected behavior. But you can also use a request
parameter to tell to the token endpoint that you don't want to submit an
authorization request. See
https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_authorization_aat
.


>
> Then is up to the owner to authorise access (via API we can do that by
> updating the permission and set granted to true)
>
> Now let’s suppose that I am the owner of the resource A, and I want to
> authorise directly (without the user asking access to the resource A)
> the user Z to access it. How can I do that? At the time being I could not
> figure it out.
>

Similar to the update method, you can use the create method to create
permissions. Is that what you are looking for ?
See org.keycloak.testsuite.authz.PermissionManagementTest#testCreatePermissionTicketWithResourceName.


>
> Also, out of curiosity is there are a way i can list all resources i can
> access thanks either to UMA permission or policies?
> That would be very handful.
>

You can do that by asking all permissions. See
https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_obtaining_permissions
.

There is an cURL example there similar to this:

curl -X POST \
  http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \
  -H "Authorization: Bearer ${access_token}" \
  --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"


In the example above you are basically, saying that you want a RPT for any
resource/scope granted to the user as a result of evaluating permissions
associated with resources which the either the user or resource server is
the owner. But yeah, depending on how many resources you will get a huge
RPT which can take some time to be issued.


>
> Suppose that you have an API that with GET /resources list you all the
> resources, there should be a way to filter the returned resources
> only based on the one you can access. This could be done easily if you
> could get a list of the resources you can access. Otherwise,
> you would need for each resource returned in the list to generate a query
> asking if the user x can access the specific resource. Not very
> scalable.
>

We don't have anything for data protection. You are not the first with this
requirement but I did not spend time thinking about this capability yet. If
you want to open a JIRA and start some discussion there I'm glad to move
this forward.


>
> Thanks!
> Federico
>
>
>
>>
>> In our understanding, to obtain 2. we should some how retrieve the
>> Requester from the TicketStore and attach the information to the response
>> (but this would "break" the UMA standard, as anyhow parameters as
>> "returnNames=true" do, so maybe when the request is using
>> "returnNames=true"
>> we could attach as well the requester name and it).
>>
>> For 1, we have no clear ideas, if not adding "requester" as well in the
>> ticket creation.
>>
>> Any hint would be highly appreciated, so that we can work up some
>> implementation to provide both features.
>>
>> Thanks,
>> Federico
>>
>> --
>> *Dr. FEDERICO MICHELE FACCA*
>> *Head of Martel Lab*
>> 0041 78 807 58 38
>> *Martel Innovate* <https://www.martel-innovate.com/>  -  Professional
>> support for innovation projects
>> Click to download our innovators' insights!
>> <https://www.martel-innovate.com/premium-content/>
>> Follow Us on Twitter <https://twitter.com/Martel_Innovate>
>> _______________________________________________
>> keycloak-dev mailing list
>> keycloak-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>
>
> *Dr. FEDERICO MICHELE FACCA*
> *Head of Martel Lab*
> 0041 78 807 58 38
> *Martel Innovate* <https://www.martel-innovate.com>  -  Professional
> support for innovation projects
> Click to download our innovators' insights!
> <https://www.martel-innovate.com/premium-content/>
> Follow Us on Twitter <https://twitter.com/Martel_Innovate>
>
>


More information about the keycloak-dev mailing list