Hi Marek,
Setting enforcement-mode=PERMISSIVE was the first thing I've tried, obviously :)
By "public endpoint" I mean completely unsecured (i.e. not mentioned under
adapter's security constraints), so in the context of your example that would be
something like "/bikes".
Dmitry
On Thu, 2019-01-31 at 11:47 +0100, Marek Posolda wrote:
On 31/01/2019 10:59, Dmitry Telegin wrote:
> My 2¢: I've been recently tasked with creating a Spring Boot + Keycloak authz
PoC. Somehow I've overlooked the existing app-authz-rest-springboot and did everything
from scratch, which allowed me to discover many surprising bugs/features/snags (hope
you'll help me to tell one from another).
>
> 1. It may sound crazy, but seems that with enforcer enabled there is no way to have
public endpoints, i.e. those that are not protected by the adapter security constraints.
I've tried every possible combination of global and per-path enforcement-mode, tried
creating the corresponding resource in Keycloak, but the enforcer would always deny
access. The only scenario that worked was setting global enforcement-mode to DISABLED,
which is obviously not an option.
>
> I'm not sure if it's Spring Boot specific or not; I'm planning to test
the same setup with other adapters too and report the result.
hmmm... Did you try enforcement-mode PERMISSIVE? I think that with that
setting, the enforcer will check just those URLs, which are mentioned
there. For all the other URLs, policy enforcer just "ignores" them and
hence just the "default" adapter checking is used (security constraint
and hence simple RBAC based protection).
For example when I had configuration like this
(
https://github.com/mposolda/devconf2019-authz/blob/master/devconf2019-ser...
- assume that everything from line 28 down was commented), then enforcer
just protected "/cars/create" URL, but all the others like
"/cars/view"
were ignored by policy enforcer.
Marek
>
> 2. When configuring path-based resource, I have automatically put double quotes
around the path like this:
>
> keycloak.policy-enforcer-config.paths[0].path="/path"
>
> Then I've killed some hours debugging the adapter trying to figure out why this
wouldn't work, only to discover that the quotes are passed to the variables verbatim,
i.e. including quotes. I think this is not something Keycloak specific, but maybe it could
be worth mentioning in the docs, in order to help folks avoid frustrating experiences like
mine.
>
> 3. {request.body[...]} pushed claim is totally broken. It drains out the servlet
input stream before the control is passed to the underlying service, so when the service
tries to process the request (which is, ehm, what services normally do) you will get
something like "org.springframework.http.converter.HttpMessageNotReadableException:
Required request body is missing". It's a well-known issue that servlet input
streams are not rewindable, so I don't see any other solution than caching the whole
request body in the memory and passing down a request wrapper.
>
> As a cherry on top, it fails to recognize JSON request body, since it tries matching
against "application/json" constant (RequestPlaceHolderResolver.java:125), and
the browser would normally send something like "application/json;
charset=UTF-8".
>
> 4. In JavaScript policies, $evaluation.context.identity.attributes has different
meaning depending on whether the policy is used in authz or fine-grained permissions. In
the first case it maps to the token claims, in the second to the custom attributes. Is
this by design? It would be nice to have a unified API for both claims and attributes.
>
> 5. Let's say we need to implement a fine-grained permission for groups, which
can be expressed as "a group admin is a user who 1) is a direct member of this group,
2) has a specific role, like group-admin". The first part can be implemented as a JS
policy, but in order to obtain a GroupModel we'll need to parse resource name (which
will be like "group.resource.e14f96e4-e06e-411f-bbdf-507e264dc33d"), extract
group ID and finally call $evaluation.authorizationProvider.realm.getGroupById().
>
> For authz resources used in fine-grained permissions, can we have a kind of link to
the model object, or something like unwrap() method that would return the same?
>
> Sorry for lengthy message, and again thanks a lot Pedro! Authorization services is a
real power feature, and your contribution has been invaluable.
>
> Kind regards,
> Dmitry Telegin
> CTO, Acutus s.r.o.
>
> On Wed, 2019-01-30 at 09:29 -0200, 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(a)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-ser...
> > > . 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-ser...
> > > . 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#ha...
> > > . 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-um...
> > > . 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.
> >
> >
> > > -- 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.
> >
> >
> > >
> > > - 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.
> >
> > Thanks !
> >
> >
> > > Marek
> > >
> > > _______________________________________________
> > > keycloak-dev mailing list
> > > keycloak-dev(a)lists.jboss.org
> > >
https://lists.jboss.org/mailman/listinfo/keycloak-dev
> > >
> >
> > _______________________________________________
> > keycloak-dev mailing list
> > keycloak-dev(a)lists.jboss.org
> >
https://lists.jboss.org/mailman/listinfo/keycloak-dev