[keycloak-dev] Authz services feedback

Marek Posolda mposolda at redhat.com
Thu Jan 31 07:26:53 EST 2019


Cool, so I created:
https://issues.jboss.org/browse/KEYCLOAK-9468 - Improve 
keycloak-authz.js to automatically exchange UMA tickets and refresh tokens
https://issues.jboss.org/browse/KEYCLOAK-9469 - Improve authorization 
java client to support automatically exchange UMA tickets and refresh 
RPT tokens

Already created yesterday for a bug in quickstarts (cased by expired 
RPT): https://issues.jboss.org/browse/KEYCLOAK-9464 app-authz-uma-photoz 
quickstart doesn't handle expired RPT

Marek

On 30/01/2019 21:40, Pedro Igor Silva wrote:
> +1 for keycloak-authz.js related changes.
>
> Regarding the java adapter, I think we could leverage our 
> java authz client for that. So, +1 for a JIRA.
>
> On Wed, Jan 30, 2019 at 6:23 PM Marek Posolda <mposolda at redhat.com 
> <mailto:mposolda at redhat.com>> wrote:
>
>     On 30/01/2019 12:29, Pedro Igor Silva wrote:
>>     Thanks for the feedback, Marek. Kudos to you too for talking
>>     about this stuff.
>>
>>     Answers inline.
>>
>>     On Wed, Jan 30, 2019 at 8:39 AM Marek Posolda
>>     <mposolda at redhat.com <mailto:mposolda at redhat.com>> wrote:
>>
>>         I recently have a chance to play a bit more with authz
>>         services when
>>         preparing for the devconf demo. Great stuff and cudos to
>>         Pedro and all
>>         the others who contributed to authorization services!
>>
>>         I just have few questions and possible suggestions to improve
>>         in the
>>         future :) Also based on some questions and discussion I had
>>         after the talk:
>>
>>         - My REST service was SpringBoot based and protected by
>>         policy enforced
>>         configured in the applications.properties like this
>>         https://github.com/mposolda/devconf2019-authz/blob/master/devconf2019-service/src/main/resources/application.properties#L23-L32
>>
>>         . However I was stuck when I wanted to enable
>>         UserManagedAccess for my
>>         service. The PolicyEnforcerConfig.UserManagedAccessConfig is
>>         an empty
>>         class and I couldn't figure how to properly add it in the
>>         application.properties file. I've tried to add various things in
>>         application.properties like this, but none of them helped:
>>
>>         keycloak.policy-enforcer-config.user-managed-access
>>         keycloak.policy-enforcer-config.user-managed-access=
>>         keycloak.policy-enforcer-config.user-managed-access= (Just
>>         left single
>>         space here after equals character) 
>>
>>
>>         As a workaround, I ended with having separate bean to do it
>>         programatically -
>>         https://github.com/mposolda/devconf2019-authz/blob/master/devconf2019-service/src/main/java/org/keycloak/quickstarts/devconf2019/config/KeycloakUMAConfigResolver.java
>>
>>         . Is it a bug or is it just me doing something stupid?
>>
>>
>>     He had some feedback in the past about that too, but the
>>     workaround you did is what people are doing. I've created
>>     https://issues.jboss.org/browse/KEYCLOAK-9458.
>>
>>     Similar issue we have when you just want to enable the
>>     policy-enforcer without any configuration. You need to specify at
>>     least one property of policy-enforcer (or create a bean).
>>
>>
>>
>>         - I wonder about possible improvements of keycloak-authz.js
>>         and if
>>         usability can be a bit improved? More specifically I mean this:
>>         -- Handling of the 401 response with UMA ticket from
>>         resource-server -
>>         Can this be done "automatically"? I meant the flow described
>>         here:
>>         https://www.keycloak.org/docs/latest/authorization_services/index.html#handling-authorization-responses-from-a-uma-protected-resource-server
>>
>>         . Maybe the keycloak-authz itself can just handle the
>>         response from
>>         resource server, then send the AuthorizationRequest to KC
>>         with the UMA
>>         ticket and then possibly re-send the request to
>>         resource-server with new
>>         RPT and do this "automatically" without a need to manually
>>         handle it by
>>         the application like this:
>>         https://github.com/keycloak/keycloak-quickstarts/blob/latest/app-authz-uma-photoz/photoz-html5-client/src/main/webapp/js/app.js#L154-L208
>>
>>         . WDYT?
>>
>>
>>     We had that before, but due to some changes in UMA specs, I
>>     decided to remove this capability from the adapter. We can
>>     discuss to get it back again.
>
>     I was thinking that adapter can provide some utility, which will
>     provide refreshing of RPT tokens (in case they are expired) and
>     also exchanging UMA tickets, which were returned from
>     resource-server for new RPT.
>
>     For example adapter can have some utility like "rptProvider",
>     which will do something like this (it will be better to have
>     proper state diagram, but hopefully you won't be lost in those
>     conditions. Imagine that from the point 1, you can go to 1.1 or 1.2):
>
>     1) check if there is existing RPT stored. If yes, it will:
>     1.1) Check if existing RPT is expired. If yes, it will:
>     1.1.1) try to refresh RPT. If refresh success, then adapter will
>     store refreshed RPT and go to (1.2)
>     1.1.2) If refresh fails, adapter will delete the existing RPT and
>     go to step 2
>     1.2) If existing RPT is not expired, adapter will just call that
>     particular "onSuccess" callback method with the RPT
>     2) If there is no RPT, adapter will use it's accessToken to call
>     authorization API
>     2.1) If calling authorization API fails, there should be
>     "onAuthzError" callback called with the error message sent to it
>     as argument (For example "request_submitted", so that caller is
>     aware that request was saved on KC side to be approved by the
>     resource owner)
>     2.2) If calling authorization API succeeds, we will store RPT and
>     go to (1.2)
>
>     --- The "onSuccess" callback will usually invoke the REST service
>     with RPT, but service can return UMA ticket in case that RPT is
>     missing some permissions. In that case, it should call some
>     builtin function provided by the authz client, which will:
>     3) Try to "parse" the UMA ticket from the response.
>     3.1) If it's not there, we need to call some "onOtherError"
>     callback method
>     3.2) If it's there, we will use that UMA ticket to call
>     authorization API - hence go again to step 2
>
>
>     Some pseudo-code how the usage of it can look like:
>
>     var rptProvider = keycloakAuthzClient.getRptProvider();
>
>     // This is the maximum timeout allowed before "rpt" needs to be
>     refreshed
>     rptProvider.setTokenMinimumTimeToLive(10);
>
>     // The "rpt" is guaranteed to NOT be expired. However it may not
>     contain permissions needed to invoke resource-server
>     rptProvider.onSuccess = function(rpt) {
>         // Just call the REST service
>         var url = 'http://localhost:8080/resource-server';
>
>         var req = new XMLHttpRequest();
>         req.open('GET', url, true);
>         req.setRequestHeader('Accept', 'application/json');
>         req.setRequestHeader('Authorization', 'Bearer ' + rpt);
>
>         req.onreadystatechange = function () {
>             if (req.readyState == 4) {
>                 if (req.status == 200) {
>                     alert('Success');
>                 } else if (req.status == 401) {
>                     // We MAY have UMA ticket in the response. Let's
>     just call "rptProvider.setUmaResponse" and then re-call "run" .
>                     // Internally, the adapter will try to parse UMA
>     ticket from the response and exchange this UMA ticket for the RPT
>     from KC server
>                     rptProvider.setUmaResponse(req);
>                     rptProvider.run();
>                 }
>             }
>         }
>
>         req.send();
>
>     });
>
>     // This callback is called when the call to KC authorization API
>     failed.
>     // The authzError can be for example "request_submitted", so the
>     caller is aware that request was created on Keycloak side and
>     needs to be approved by the resource owner
>     rptProvider.onAuthzError(function(authzError) {
>
>     });
>
>     // This callback is called on any other error. For example when
>     resource-server returns some other error response than "401" with
>     UMA ticket
>     rptProvider.onOtherError(function(errorDetails) {
>
>     });
>
>     // This will trigger the described flow
>     rptProvider.run();
>
>
>>
>>         -- Another thing is refreshing of RPT. It looks that RPT
>>         response
>>         contains the refresh token, so refreshing of RPTs is
>>         possible. However
>>         the keycloak-authz.js client doesn't have any support for
>>         automatically
>>         refreshing RPT token. I mean something similar, which is
>>         provided by
>>         keycloak.js itself (method "keycloak.updateToken" which
>>         automatically
>>         refreshes the token if needed). Due this limitation, it seems
>>         there is a
>>         bug in our quickstart. When you try the quickstart
>>         "app-authz-uma-photoz" and you go through the flow like this:
>>         - Open http://localhost:8080/photoz-html5-client and login as
>>         jdoe
>>         - Create some album
>>         - Wait 10 minutes (RPT expiration is same like
>>         AccessTokenLifespan, so 5
>>         minutes by default)
>>         - Try to create some album again - now fails with 403 due the
>>         RPT
>>         expired and no support for refreshing it in the
>>         keycloak-authz.js or the
>>         application itself.
>>         Should I create JIRA for this?
>>
>>
>>     Yes, please.
>     Created https://issues.jboss.org/browse/KEYCLOAK-9464
>>
>>
>>
>>         - It seems we don't have any Java based adapter for the
>>         frontend clients
>>         written in Java? We have Java based authorization client, but
>>         that
>>         provides just sending REST requests. It doesn't provide
>>         things like I
>>         mentioned above though (Storing RPT, automatically refreshing
>>         RPT,
>>         Automatically handling 401 response with the UMA ticket from
>>         resource-server and sending the request to KC etc). Any plan
>>         to have this?
>>
>>
>>     Could we leverage the authz client for that ? If you could create
>>     a JIRA with more details about the scenarios we are trying to
>>     support, we can start thinking about a solution.
>
>     I was thinking about something quite similar like the javascript
>     client (keycloak-authz.js) will provide. If we agree on the
>     javascript client, hopefully java can have something similar.
>
>     Marek
>
>>
>>     Thanks !
>>
>>
>>         Marek
>>
>>         _______________________________________________
>>         keycloak-dev mailing list
>>         keycloak-dev at lists.jboss.org
>>         <mailto:keycloak-dev at lists.jboss.org>
>>         https://lists.jboss.org/mailman/listinfo/keycloak-dev
>>
>



More information about the keycloak-dev mailing list