New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow direct access to the keycloak PolicyEnforcer or the AuthzClient #16972
Comments
/cc @pedroigor |
@joggeli34 I'm not sure this enhancement is needed, can you please be more specific why would you like to have it ? What I think we can do though is to have |
|
My use case is the following: Assume we have several resources like My plan was to disable the authorization for the path @Path("/items")
public class ItemResource {
@Inject
AuthzClient authzClient;
@Inject
JsonWebToken accessToken;
@Path("")
@NoCache
public String getItems() {
// create an authorization request
AuthorizationRequest request = new AuthorizationRequest();
// send the entitlement request to the server in order to
// obtain an RPT with all permissions granted to the user
AuthorizationResponse response = authzClient.authorization(accessToken.getRawToken()).authorize(request);
String rpt = response.getToken();
// introspect the token
TokenIntrospectionResponse requestingPartyToken = authzClient.protection().introspectRequestingPartyToken(rpt);
for (Permission granted : requestingPartyToken.getPermissions()) {
// TODO get all the items belonging to the resources in the permissions
var items = ...;
}
return items;
}
} The I think on the Or is there a other way to implement this which I haven't discovered yet? Regards |
The second use case is, that when someone is adding a new item to our service, we like to automatically create a new keycloak-resource for it, which can also be done with the |
@joggeli34 We support that when using Keycloak Adapters but not here. Adding it. |
@joggeli34 thanks for the clarifications |
HI guys, I'm having a similar use case with getting all permissions for all resources for a specifc path to check the access to the items. Seeing the comments in this thread and checking the pull request I thougt to integrate the AutzClient is to us the quarkus version "2.0.0.Alpha3" and then accessing the AuthzClient by injecting it. Bootstraping the project: mvn io.quarkus:quarkus-maven-plugin:2.0.0.Alpha3:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=quarkus-keycloak-20alpha3 \
-DclassName="org.acme.keycloak.EventResource" \
-Dpath="/events" \
-Dextensions="oidc,keycloak-authorization,resteasy,resteasy-jackson,resteasy-mutiny" Having the following pom: <?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>quarkus-keycloak-20alpha3</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus-plugin.version>2.0.0.Alpha3</quarkus-plugin.version>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<quarkus.platform.version>2.0.0.Alpha3</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-mutiny</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-keycloak-authorization</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<parameters>${maven.compiler.parameters}</parameters>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project> Injecting the AuthzClient as follows: package org.acme.keycloak;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.keycloak.authorization.client.AuthzClient;
import io.quarkus.security.identity.SecurityIdentity;
@Path("/events")
public class EventResource {
@Inject
SecurityIdentity identity;
@Inject
AuthzClient authzClient;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy";
}
} I'm getting the following error message: 2021-06-24 13:39:31,160 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (vert.x-worker-thread-1) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.keycloak.authorization.client.AuthzClient and qualifiers [@Default]
- java member: org.acme.keycloak.EventResource#authzClient
- declared on CLASS bean [types=[org.acme.keycloak.EventResource, java.lang.Object], qualifiers=[@Default, @Any], target=org.acme.keycloak.EventResource]
at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1098)
at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:264)
at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:413)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:820)
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:832)
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: org.acme.keycloak.EventResource#authzClient
- declared on CLASS bean [types=[org.acme.keycloak.EventResource, java.lang.Object], qualifiers=[@Default, @Any], target=org.acme.keycloak.EventResource]
at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:492)
at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:460)
at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:252)
... 12 more
... Any idea or tipps how to use the AuthzClient to get the permissions / resources? Thanks and cheers. |
I think you need to set this to true to be able to inject the AuthzClient: |
Description
When using quarkus-keycloak-authorization, it would be nice when the AuthzClient or the PolicyEnforcer could be injected, or at least be retreived from the KeycloakPolicyEnforcerAuthorizer.
This way, it's not necessary to create a second AuthzClient for configuring the authorization from within the application. Sometimes its also necessary to get the user entitlements for collection-rest-endpoints that deliver all items a user has access to.
Implementation ideas
First Idea: Create the PolicyEnforcer as a bean and also inject it in the KeycloakPolicyEnforcerAuthorizer.
Second Idea: Just keep the PolicyEnforcer as a field on the KeycloakPolicyEnforcerAuthorizer with a public getter.
Regards, Adrian
The text was updated successfully, but these errors were encountered: