[keycloak-user] API Authorization: on request or response?

Corentin Dupont corentin.dupont at gmail.com
Wed Nov 15 06:11:01 EST 2017


Sorry to disturb again, another small question:
It seems that with the Keycloak UI I cannot choose the owner of a resource,
but with the API I can? Is that correct?
Thanks

On Tue, Nov 14, 2017 at 9:43 PM, Pedro Igor Silva <psilva at redhat.com> wrote:

> In the first case you should get an error instead. Will check the second
> case as in theory it should just ignore the scope.
>
> On Tue, Nov 14, 2017 at 2:32 PM, Corentin Dupont <
> corentin.dupont at gmail.com> wrote:
>
>> I spotted something strange:
>> If I try with a non existing resource:
>>
>> $ curl -X POST -H "Content-Type: application/json" -H "Authorization:
>> Bearer $TOKEN" -d '{
>>     "permissions" : [
>>         {
>>             "resource_set_name" : "xxx",
>>             "scopes" : [
>>                 "view"
>>             ]
>>         }
>>     ]
>> }'  "http://localhost:8080/auth/realms/waziup/authz/entitlement/waziup"
>>
>> It replies with 200:
>> {"rpt":"eyJhbG...}
>> Is this correct?
>>
>> If I try also with a non existent scope (yes I'm nitpicking):
>>
>> $ curl -X POST -H "Content-Type: application/json" -H "Authorization:
>> Bearer $TOKEN" -d '{
>>     "permissions" : [
>>         {
>>             "resource_set_name" : "xxx",
>>             "scopes" : [
>>                 "xxx"
>>             ]
>>         }
>>     ]
>> }'  "http://localhost:8080/auth/realms/waziup/authz/entitlement/waziup"
>>
>>
>> It replies with 500: Internal Server Error
>>
>> On Tue, Nov 14, 2017 at 2:13 PM, Corentin Dupont <
>> corentin.dupont at gmail.com> wrote:
>>
>>> This works great, thanks.
>>>
>>> TOKEN=`curl -X POST \
>>>     -H "Content-Type: application/x-www-form-urlencoded" \
>>>     -d 'grant_type=client_credentials&client_id=myclient&client_sec
>>> ret=myclientsecret'
>>>     "http://localhost:8080/auth/realms/${realm_name}/protocol/op
>>> enid-connect/token" | jq .access_token -r`
>>>
>>> Then I do:
>>> $ curl "http://localhost:8080/auth/realms/myrealm/authz/protection/
>>> resource_set" -H "Authorization: Bearer $TOKEN"
>>> ["037f5d3e-8f25-4af1-93a0-4e17455d0614"]
>>> $ curl "http://localhost:8080/auth/realms/myrealm/authz/protection/
>>> resource_set/037f5d3e-8f25-4af1-93a0-4e17455d0614" -H "Authorization:
>>> Bearer $TOKEN"
>>> {
>>> "name": "Sensors",
>>> "uri": "/sensors/*",
>>> "type": "http://localhost:3000/sensors",
>>> "scopes": [
>>> {
>>> "id": "da776461-c1f5-4904-a559-1ca04d9f53a9",
>>> "name": "view"
>>> },
>>> {
>>> "id": "2615157c-f588-4e2b-ba1c-720fe8394215",
>>> "name": "manage"
>>> }
>>> ],
>>> "owner": "0892e431-5daf-413e-b4cf-eaee121ee447",
>>> "_id": "037f5d3e-8f25-4af1-93a0-4e17455d0614",
>>> "id": "037f5d3e-8f25-4af1-93a0-4e17455d0614"
>>> }
>>>
>>> Next I tried to POST a new resource:
>>> curl -X POST "http://localhost:8080/auth/re
>>> alms/waziup/authz/protection/resource_set" -H "Content-Type:
>>> application/json" -H "Authorization: Bearer $TOKEN" -d '{
>>> "name": "My house",
>>> "uri": "/houses/123",
>>> "scopes": [
>>> {
>>> "id": "da776461-c1f5-4904-a559-1ca04d9f53a9",
>>> "name": "view"
>>> },
>>> {
>>> "id": "2615157c-f588-4e2b-ba1c-720fe8394215",
>>> "name": "manage"
>>> }
>>> ],
>>> "owner": "0892e431-5daf-413e-b4cf-eaee121ee447"
>>> }'
>>>
>>> Everything seems OK.
>>>
>>>
>>> On Tue, Nov 14, 2017 at 1:44 PM, Pedro Igor Silva <psilva at redhat.com>
>>> wrote:
>>>
>>>> Try this:
>>>>
>>>> curl -X POST \
>>>>     -H "Content-Type: application/x-www-form-urlencoded" \
>>>>     -d 'grant_type=client_credentials&client_id=myclient&client_sec
>>>> ret=myclientsecret'
>>>>     "http://localhost:8080/auth/realms/${realm_name}/protocol/op
>>>> enid-connect/token"
>>>>
>>>> Without BASIC but credentials as form parameters.
>>>>
>>>> On Tue, Nov 14, 2017 at 10:37 AM, Corentin Dupont <
>>>> corentin.dupont at gmail.com> wrote:
>>>>
>>>>> Thanks, actually I saw it but I didn't understand where this bit came
>>>>> from: aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpwYXNzd29yZA==
>>>>>
>>>>> On Tue, Nov 14, 2017 at 1:20 PM, Pedro Igor Silva <psilva at redhat.com>
>>>>> wrote:
>>>>>
>>>>>> The problem here is that you got an access token (that you are using
>>>>>> as a bearer to access Protection API) using resource owner password grant
>>>>>> type (direct grant). That means the subject of the token is an user
>>>>>> (username) and not the resource server itself.
>>>>>>
>>>>>> Only resource servers (your client application) are allowed to access
>>>>>> the Protection API (and managed resources).
>>>>>>
>>>>>> The access token you got is valid to query for permissions though. As
>>>>>> you want to obtain a set of permission an user has. Where the token
>>>>>> represents user identity.
>>>>>>
>>>>>> You should fix that error by obtaining a access token for your
>>>>>> client. Something like that (from docs):
>>>>>>
>>>>>> curl -X POST \
>>>>>>     -H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpwYXNzd29yZA==" \
>>>>>>     -H "Content-Type: application/x-www-form-urlencoded" \
>>>>>>     -d 'grant_type=client_credentials' \
>>>>>>     "http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token"
>>>>>>
>>>>>>
>>>>>> On Tue, Nov 14, 2017 at 7:47 AM, Corentin Dupont <
>>>>>> corentin.dupont at gmail.com> wrote:
>>>>>>
>>>>>>> Thanks for the documentation, after reading it I found that I can
>>>>>>> use "entitlement" endpoints for my use case.
>>>>>>> So I do:
>>>>>>>
>>>>>>> TOKEN=`curl -X POST  -H "Content-Type: application/x-www-form-urlencoded"
>>>>>>> -d 'username=username&password=password&grant_type=password&cli
>>>>>>> ent_id=myclient&client_secret=myclientsecret' "
>>>>>>> http://localhost:8080/auth/realms/myrealm/protocol/openid-c
>>>>>>> onnect/token" | jq .access_token -r`
>>>>>>>
>>>>>>> curl -X POST -H "Content-Type: application/json" -H "Authorization:
>>>>>>> Bearer $TOKEN" -d '{
>>>>>>>     "permissions" : [
>>>>>>>         {
>>>>>>>             "resource_set_name" : "Houses",
>>>>>>>             "scopes" : [
>>>>>>>                 "view"
>>>>>>>             ]
>>>>>>>         }
>>>>>>>     ]
>>>>>>> }'  "http://localhost:8080/auth/realms/myrealm/authz/entitlement
>>>>>>> /myclient"
>>>>>>>
>>>>>>> Is this correct? It seems to be working.
>>>>>>> I am not sure how can I get/create resources via the API.
>>>>>>> I tried:
>>>>>>>
>>>>>>> curl "http://localhost:8080/auth/realms/myrealm/authz/protection/
>>>>>>> resource_set" -H "Authorization: Bearer $TOKEN"
>>>>>>> But I get:
>>>>>>> {"error":"invalid_clientId","error_description":"Client application
>>>>>>> with id [2ecfae24-f340-4ad0-a12e-02cdc60cd8ba] does not exist in
>>>>>>> realm [myrealm]"}
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Nov 13, 2017 at 6:11 PM, Corentin Dupont <
>>>>>>> corentin.dupont at gmail.com> wrote:
>>>>>>>
>>>>>>>> Hi again,
>>>>>>>> I looked everywhere but I couldn't find an Evaluation API for
>>>>>>>> javascript...
>>>>>>>> In my nodeJS server, should I call UMA API endpoints?
>>>>>>>>
>>>>>>>> On Mon, Nov 13, 2017 at 12:34 PM, Pedro Igor Silva <
>>>>>>>> psilva at redhat.com> wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> It seems you are looking for fine-grained permissions. Could you
>>>>>>>>> take a look at this example [1] and documentation [2] ?
>>>>>>>>>
>>>>>>>>> One of the things shown by that example is how to protect
>>>>>>>>> resources based on its owner.
>>>>>>>>>
>>>>>>>>> [1] https://github.com/keycloak/keycloak/tree/master/example
>>>>>>>>> s/authz/photoz
>>>>>>>>> [2] http://www.keycloak.org/docs/latest/authorization_servic
>>>>>>>>> es/index.html
>>>>>>>>>
>>>>>>>>> On Sun, Nov 12, 2017 at 7:14 PM, Corentin Dupont <
>>>>>>>>> corentin.dupont at gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> Hi guys,
>>>>>>>>>> another small question :)
>>>>>>>>>>
>>>>>>>>>> Suppose you have an API looking like this:
>>>>>>>>>> http://www.example.com/api/v1/cars
>>>>>>>>>>
>>>>>>>>>> Cars have an owner:
>>>>>>>>>> {
>>>>>>>>>>   name: "my car"
>>>>>>>>>>   owner: "smith"
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> How to make sure that you can only get cars that are yours (you
>>>>>>>>>> can have
>>>>>>>>>> several cars)?
>>>>>>>>>> If you make a simple GET on this endpoint, should I:
>>>>>>>>>> 1. just reply with a "Access denied" because the request is too
>>>>>>>>>> large: it
>>>>>>>>>> could yield cars that are not yours,
>>>>>>>>>> 2. reply with "Access denied" if the response list contains some
>>>>>>>>>> cars that
>>>>>>>>>> are not yours,
>>>>>>>>>> 3. filter the response car list with only yours?
>>>>>>>>>>
>>>>>>>>>> It seems that 1. is the simplest because it uses only the request
>>>>>>>>>> to make
>>>>>>>>>> decisions.
>>>>>>>>>> 2. uses the response to make decision, while 3. requires the
>>>>>>>>>> collaboration
>>>>>>>>>> of the response handler in my API server, in order to implement
>>>>>>>>>> the
>>>>>>>>>> filtering.
>>>>>>>>>> What is the most standard way?
>>>>>>>>>>
>>>>>>>>>> I have also some trouble understanding how to implement that with
>>>>>>>>>> Keycloak
>>>>>>>>>> protect in NodeJS.
>>>>>>>>>> Cheers!!
>>>>>>>>>> Corentin
>>>>>>>>>> _______________________________________________
>>>>>>>>>> keycloak-user mailing list
>>>>>>>>>> keycloak-user at lists.jboss.org
>>>>>>>>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>


More information about the keycloak-user mailing list