[keycloak-user] Keycloak AuthZ Client - Link resource/scope to policy/permission via API

Pedro Igor Craveiro e Silva psilva at redhat.com
Wed Oct 19 07:05:48 EDT 2016


For resource management you should use AuthZ Client API. Here are some
examples [1] about how to use this API and manage resources.

Remote Resource Management is achieved by using our Protection API [2].
Which is basically a UMA compliant endpoint for resource management
operations.

You can also look at PhotoZ Example [3] and see how we are using AuthZ
Client + Protection API (Resource Registration) to manage resources
remotely.

Regarding the 400 error, you are not using the API correctly. When
using Keycloak Admin Client, the first thing you need to do is obtain a
AuthorizationResource for a given client/resource server:

// get the client
ClientRepresentation foo = realm.clients().findByClientId("foo-
authz").get(0);

// get the AuthorizationResource
AuthorizationResource authorization =
realm.clients().get(foo.getId()).authorization();

>From AuthorizationResource you have access to the same operations used
by Keycloak Admin Console in order to manage authorization settings for
a specific client/resource server.

For some real examples about how to use AuthorizationResource, you may
want to look at this test [4]. There we manage resources, scopes,
permissions, policies, etc. 

Like I said, we are lacking policy management via Authz Client API.
That is the right way to do it. 

For now the only way to achieve that is using Keycloak Admin Client. If
you really want to use Keycloak Admin Client for such operations,
please do it in a way that you can easily replace the code once we
update Authz Client API.

Regards.
Pedro Igor

[1] https://keycloak.gitbooks.io/authorization-services-guide/content/t
opics/service/client-api.html

[2] https://keycloak.gitbooks.io/authorization-services-guide/content/t
opics/service/protection/resources-api-papi.html

[3] https://github.com/keycloak/keycloak/blob/master/examples/authz/pho
toz/photoz-restful-
api/src/main/java/org/keycloak/example/photoz/album/AlbumService.java#L
110

[4] https://github.com/keycloak/keycloak/blob/master/testsuite/integrat
ion-
arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/exam
ple/authorization/AbstractPhotozExampleAdapterTest.java

On Wed, 2016-10-19 at 09:35 +0000, FREIMUELLER Christian wrote:
> Hi,
> 
> me again on the same topic.
> 
> I’ve created a test realm called “test-realm” with a test client
> called “MyClient” and turned that one into a resource server via HMI
> and allowed remote resource creation.
> 
> I tried to keep it simple for the test and created a
> ClientRepresentation instance with one resource and on policy.
> When I try to update the client using the Admin Client API
> "/admin/realms/{realm}/clients/{id}"
> 
> In particular: /admin/realms/test-realm/clients/9d274eb7-e01e-4e6d-
> b9e9-eb384fa30170
> 
> The client object is transformed into the following JSON and sent to
> the Keycloak server 
> 
> {
>   "name" : "MyClient",
>   "authorizationServicesEnabled" : true,
>   "authorizationSettings" : {
>     "allowRemoteResourceManagement" : true,
>     "policyEnforcementMode" : "ENFORCING",
>     "resources" : [ {
>       "name" : "ResourceName1",
>       "policies" : [ {
>         "id" : "PolicyId1",
>         "name" : "PolicyName1",
>         "logic" : "POSITIVE",
>         "decisionStrategy" : "AFFIRMATIVE",
>         "config" : { }
>       } ],
>       "_id" : "ResourceID1"
>     } ],
>     "policies" : [ {
>       "id" : "PolicyId1",
>       "name" : "PolicyName1",
>       "logic" : "POSITIVE",
>       "decisionStrategy" : "AFFIRMATIVE",
>       "config" : { }
>     } ],
>     "scopes" : [ ]
>   }
> }
> 
> I receive a "400 Bad Request" response on the client side and on the
> server the following exception is thrown (detailed stack trace
> below):
> com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
> Unrecognized field "authorizationSettings"
> 
> I also tried remote debugging and indeed, this property of Client
> Representation is not in the known properties list when Jackson tries
> to deserialize the JSON.
> 
> Am I using the correct API for providing the policy/resource
> information?
> 
> How can I make Jackson aware of the field “authorizationSettings”?
> 
> Any other suggestions for managing the resources remotely?
> 
> Kind regards,
> Christian
> 
> 
> 
> 
> 
> 2016-10-19 10:13:12,258 ERROR
> [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-38)
> RESTEASY002005: Failed executing PUT /admin/realms/test-
> realm/clients/9d274eb7-e01e-4e6d-b9e9-eb384fa30170:
> org.jboss.resteasy.spi.ReaderException:
> com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
> Unrecognized field "authorizationSettings" (class
> org.keycloak.representations.idm.ClientRepresentation), not marked as
> ignorable (36 known properties: "enabled", "clientAuthenticatorType",
> "redirectUris", "useTemplateConfig", "clientId",
> "serviceAccountsEnabled", "authorizationServicesEnabled", "name",
> "implicitFlowEnabled", "registeredNodes",
> "nodeReRegistrationTimeout", "publicClient", "attributes",
> "protocol", "webOrigins", "consentRequired", "protocolMappers", "id",
> "baseUrl", "surrogateAuthRequired", "adminUrl", "fullScopeAllowed",
> "frontchannelLogout", "clientTemplate", "directGrantsOnly",
> "rootUrl", "bearerOnly", "secret", "useTemplateMappers", "notBefore",
> "useTemplateScope", "standardFlowEnabled", "description",
> "defaultRoles", "registrationAccessToken",
> "directAccessGrantsEnabled"])
>  at [Source: io.undertow.servlet.spec.ServletInputStreamImpl at 1f8c2096
> ; line: 1, column: 84] (through reference chain:
> org.keycloak.representations.idm.ClientRepresentation["authorizationS
> ettings"])
> 	at
> org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBo
> dyParameterInjector.java:184)
> 	at
> org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInje
> ctorImpl.java:91)
> 	at
> org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.
> java:114)
> 	at
> org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(Resource
> MethodInvoker.java:295)
> 	at
> org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodIn
> voker.java:249)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(R
> esourceLocatorInvoker.java:138)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocator
> Invoker.java:107)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(R
> esourceLocatorInvoker.java:133)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocator
> Invoker.java:107)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(R
> esourceLocatorInvoker.java:133)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocator
> Invoker.java:107)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(R
> esourceLocatorInvoker.java:133)
> 	at
> org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocator
> Invoker.java:101)
> 	at
> org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispa
> tcher.java:395)
> 	at
> org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispa
> tcher.java:202)
> 	at
> org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.
> service(ServletContainerDispatcher.java:221)
> 	at
> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.servi
> ce(HttpServletDispatcher.java:56)
> 	at
> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.servi
> ce(HttpServletDispatcher.java:51)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
> 	at
> io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHand
> ler.java:85)
> 	at
> io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(F
> ilterHandler.java:129)
> 	at
> org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(K
> eycloakSessionServletFilter.java:90)
> 	at
> io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60
> )
> 	at
> io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(F
> ilterHandler.java:131)
> 	at
> io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandle
> r.java:84)
> 	at
> io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.hand
> leRequest(ServletSecurityRoleHandler.java:62)
> 	at
> io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(
> ServletDispatchingHandler.java:36)
> 	at
> org.wildfly.extension.undertow.security.SecurityContextAssociationHan
> dler.handleRequest(SecurityContextAssociationHandler.java:78)
> 	at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateH
> andler.java:43)
> 	at
> io.undertow.servlet.handlers.security.SSLInformationAssociationHandle
> r.handleRequest(SSLInformationAssociationHandler.java:131)
> 	at
> io.undertow.servlet.handlers.security.ServletAuthenticationCallHandle
> r.handleRequest(ServletAuthenticationCallHandler.java:57)
> 	at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateH
> andler.java:43)
> 	at
> io.undertow.security.handlers.AbstractConfidentialityHandler.handleRe
> quest(AbstractConfidentialityHandler.java:46)
> 	at
> io.undertow.servlet.handlers.security.ServletConfidentialityConstrain
> tHandler.handleRequest(ServletConfidentialityConstraintHandler.java:6
> 4)
> 	at
> io.undertow.security.handlers.AuthenticationMechanismsHandler.handleR
> equest(AuthenticationMechanismsHandler.java:60)
> 	at
> io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandl
> er.handleRequest(CachedAuthenticatedSessionHandler.java:77)
> 	at
> io.undertow.security.handlers.NotificationReceiverHandler.handleReque
> st(NotificationReceiverHandler.java:50)
> 	at
> io.undertow.security.handlers.AbstractSecurityContextAssociationHandl
> er.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
> 	at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateH
> andler.java:43)
> 	at
> org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.han
> dleRequest(JACCContextIdHandler.java:61)
> 	at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateH
> andler.java:43)
> 	at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateH
> andler.java:43)
> 	at
> io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest
> (ServletInitialHandler.java:284)
> 	at
> io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(Se
> rvletInitialHandler.java:263)
> 	at
> io.undertow.servlet.handlers.ServletInitialHandler.access$000(Servlet
> InitialHandler.java:81)
> 	at
> io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(Se
> rvletInitialHandler.java:174)
> 	at
> io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
> 	at
> io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:7
> 93)
> 	at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
> java:1142)
> 	at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
> .java:617)
> 	at java.lang.Thread.run(Thread.java:745)
> Caused by:
> com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
> Unrecognized field "authorizationSettings" (class
> org.keycloak.representations.idm.ClientRepresentation), not marked as
> ignorable (36 known properties: "enabled", "clientAuthenticatorType",
> "redirectUris", "useTemplateConfig", "clientId",
> "serviceAccountsEnabled", "authorizationServicesEnabled", "name",
> "implicitFlowEnabled", "registeredNodes",
> "nodeReRegistrationTimeout", "publicClient", "attributes",
> "protocol", "webOrigins", "consentRequired", "protocolMappers", "id",
> "baseUrl", "surrogateAuthRequired", "adminUrl", "fullScopeAllowed",
> "frontchannelLogout", "clientTemplate", "directGrantsOnly",
> "rootUrl", "bearerOnly", "secret", "useTemplateMappers", "notBefore",
> "useTemplateScope", "standardFlowEnabled", "description",
> "defaultRoles", "registrationAccessToken",
> "directAccessGrantsEnabled"])
>  at [Source: io.undertow.servlet.spec.ServletInputStreamImpl at 1f8c2096
> ; line: 1, column: 84] (through reference chain:
> org.keycloak.representations.idm.ClientRepresentation["authorizationS
> ettings"])
> 	at
> com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from
> (UnrecognizedPropertyException.java:51)
> 	at
> com.fasterxml.jackson.databind.DeserializationContext.reportUnknownPr
> operty(DeserializationContext.java:817)
> 	at
> com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknow
> nProperty(StdDeserializer.java:958)
> 	at
> com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnkno
> wnProperty(BeanDeserializerBase.java:1324)
> 	at
> com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnkno
> wnVanilla(BeanDeserializerBase.java:1302)
> 	at
> com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserial
> ize(BeanDeserializer.java:249)
> 	at
> com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(Bea
> nDeserializer.java:136)
> 	at
> com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1
> 410)
> 	at
> com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.ja
> va:860)
> 	at
> org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider
> .readFrom(ResteasyJackson2Provider.java:121)
> 	at
> org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext
> .readFrom(AbstractReaderInterceptorContext.java:61)
> 	at
> org.jboss.resteasy.core.interception.ServerReaderInterceptorContext.r
> eadFrom(ServerReaderInterceptorContext.java:60)
> 	at
> org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext
> .proceed(AbstractReaderInterceptorContext.java:53)
> 	at
> org.jboss.resteasy.security.doseta.DigitalVerificationInterceptor.aro
> undReadFrom(DigitalVerificationInterceptor.java:34)
> 	at
> org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext
> .proceed(AbstractReaderInterceptorContext.java:55)
> 	at
> org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingIntercep
> tor.aroundReadFrom(GZIPDecodingInterceptor.java:59)
> 	at
> org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext
> .proceed(AbstractReaderInterceptorContext.java:55)
> 	at
> org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBo
> dyParameterInjector.java:151)
> 	... 50 more
> 
> -----Original Message-----
> From: FREIMUELLER Christian 
> Sent: 19 October 2016 08:27
> To: 'Pedro Igor Craveiro e Silva'
> Cc: keycloak-user at lists.jboss.org
> Subject: RE: [keycloak-user] Keycloak AuthZ Client - Link
> resource/scope to policy/permission via API
> 
> Thanks, Pedro for the information - that helped me a lot. 
> 
> I will try to achieve this with the Admin Client API - I think you
> are referring to the clients CRUD API, aren't you?
> 
> When is the improvement on the client API and REST API planned? ->
> the mentioned ticket below is currently without a proposed fix
> version...
> 
> Kind regards,
> Christian
> 
> -----Original Message-----
> From: Pedro Igor Craveiro e Silva [mailto:psilva at redhat.com> Sent: 18 October 2016 16:34
> To: FREIMUELLER Christian; keycloak-user at lists.jboss.org
> Subject: Re: [keycloak-user] Keycloak AuthZ Client - Link
> resource/scope to policy/permission via API
> 
> Hi Christian.
> 
> Currently we don't support that, but we have KEYCLOAK-3135 [1] which
> I
> think is related with what you are looking for.
> 
> Actually, you can already do that via Keycloak Admin Client API, but
> we
> would like to come up with a better Client API and REST API for that.
> 
> Our roadmap includes not only URI protection, but also other uses
> cases
> supported by UMA.
> 
> [1] https://issues.jboss.org/browse/KEYCLOAK-3135
> 
> On Tue, 2016-10-18 at 14:11 +0000, FREIMUELLER Christian wrote:
> > 
> > Dear all,
> > 
> > I've a question regarding the authZ client.
> > 
> > Is there a way to connect the resources created with the client
> > with
> > policies/permissions via the API, or is there only the HMI (Admin
> > Console) to make this connection?
> > 
> > The thing is we would like to use Keycloak for defining the access
> > rights on thousands of resources (objects like database entries,
> > files) and it would be very cumbersome to do this by hand for each
> > single resource.
> > 
> > Or is this authorization service meant to be used in another way
> > (protecting URI for applications) only?
> > 
> > Best regards,
> > Christian
> > _______________________________________________
> > keycloak-user mailing list
> > keycloak-user at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/keycloak-user
> -- 
> Pedro Igor
-- 
Pedro Igor


More information about the keycloak-user mailing list