An error occured when injecting AuthzClient

Viewed 354

Injecting AuthzClient in quarkus 1.13 an error occured.

@Inject
AuthzClient authzClient;
Caused by: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.keycloak.authorization.client.AuthzClient and qualifiers [@Default]
        - java member: io.github.jithset.services.KeycloakServices#authzClient
        - declared on CLASS bean [types=[io.github.jithset.services.KeycloakServices, java.lang.Object], qualifiers=[@Default, @Any], target=io.github.jithset.services.KeycloakServices]
        at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1081)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:255)
        at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
        at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:419)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:920)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
        at java.base/java.lang.Thread.run(Thread.java:829)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.keycloak.authorization.client.AuthzClient and qualifiers [@Default]
        - java member: io.github.jithset.services.KeycloakServices#authzClient
        - declared on CLASS bean [types=[io.github.jithset.services.KeycloakServices, java.lang.Object], qualifiers=[@Default, @Any], target=io.github.jithset.services.KeycloakServices]
        at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:484)
        at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:378)
        at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:247)

If that is not possible how can i check if user has certain permission with access token.

Thanks

2 Answers

I do not agree with @loicmathieu and @Ladicek. If you want to manage protected resources you NEED to be able to inject the AuthzClient.

This a common usecase when you want to implement user managed authorization. A good example is in the keycloak quickstart repo : https://github.com/keycloak/keycloak-quickstarts/tree/latest/app-authz-uma-photoz.

There is an IT test where the AuthzClient is injected in the official quarkus repository : https://github.com/quarkusio/quarkus/blob/9b09229b86b775a9452d09fca42f18e32f81e924/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/ProtectedResource.java

And the use of the AuthzClient is documented here : https://quarkus.io/guides/security-keycloak-authorization#injecting-the-authorization-client

After some experimentation I found that the AuthzClient bean will only exist when quarkus.keycloak.policy-enforcer.enable=true is added to the configuration.

The easiest way to check for permissions is to use the security annotations as explained in the USING OAUTH2 RBAC guide or injext the security context via @Context SecurityContext ctx.

If you want to have access to the token, assuming you're using the authorization code flow, you can inject the JWT token via @Inject JwtToken jwtToken, more details in the USING OPENID CONNECT TO PROTECT WEB APPLICATIONS USING AUTHORIZATION CODE FLOW guide.

If you"re using Keycloack, you can also inject a io.quarkus.security.identity.SecurityIdentity but as @Ladicek said you're not supposed to directly used internal Keycloack classes, see the USING OPENID CONNECT AND KEYCLOAK TO CENTRALIZE AUTHORIZATION guide.

Related