[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