Skip to content

Commit 6c3a543

Browse files
authored
Merge pull request #50333 from michalvavrik/feature/fix-oidc-redis-token-man-native
Fix OIDC Redis Token State Manager serialization in native mode
2 parents 26a3ca5 + fab2953 commit 6c3a543

File tree

6 files changed

+65
-13
lines changed

6 files changed

+65
-13
lines changed

extensions/oidc-redis-token-state-manager/deployment/src/main/java/io/quarkus/oidc/redis/token/state/manager/deployment/OidcRedisTokenStateManagerProcessor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
import io.quarkus.deployment.annotations.BuildSteps;
1313
import io.quarkus.deployment.annotations.ExecutionTime;
1414
import io.quarkus.deployment.annotations.Record;
15+
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
1516
import io.quarkus.oidc.TokenStateManager;
17+
import io.quarkus.oidc.redis.token.state.manager.runtime.AuthorizationCodeTokensRecord;
1618
import io.quarkus.oidc.redis.token.state.manager.runtime.OidcRedisTokenStateManagerRecorder;
1719
import io.quarkus.redis.client.RedisClientName;
1820
import io.quarkus.redis.datasource.ReactiveRedisDataSource;
@@ -27,6 +29,12 @@ RequestedRedisClientBuildItem requestRedisClient(OidcRedisTokenStateManagerBuild
2729
return new RequestedRedisClientBuildItem(buildConfig.redisClientName());
2830
}
2931

32+
@BuildStep
33+
ReflectiveClassBuildItem registerTokenStateRecordForReflection() {
34+
return ReflectiveClassBuildItem.builder(AuthorizationCodeTokensRecord.class)
35+
.serialization().fields().methods().constructors().build();
36+
}
37+
3038
@Record(ExecutionTime.STATIC_INIT)
3139
@BuildStep
3240
SyntheticBeanBuildItem createTokenStateManager(OidcRedisTokenStateManagerRecorder recorder,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.quarkus.oidc.redis.token.state.manager.runtime;
2+
3+
import io.quarkus.oidc.AuthorizationCodeTokens;
4+
5+
public record AuthorizationCodeTokensRecord(String idToken, String accessToken, String refreshToken, Long accessTokenExpiresIn,
6+
String accessTokenScope) {
7+
8+
static AuthorizationCodeTokensRecord of(AuthorizationCodeTokens tokens) {
9+
return new AuthorizationCodeTokensRecord(tokens.getIdToken(), tokens.getAccessToken(), tokens.getRefreshToken(),
10+
tokens.getAccessTokenExpiresIn(), tokens.getAccessTokenScope());
11+
}
12+
13+
AuthorizationCodeTokens toTokens() {
14+
return new AuthorizationCodeTokens(idToken, accessToken, refreshToken, accessTokenExpiresIn, accessTokenScope);
15+
}
16+
}

extensions/oidc-redis-token-state-manager/runtime/src/main/java/io/quarkus/oidc/redis/token/state/manager/runtime/OidcRedisTokenStateManager.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,4 @@ private static SetArgs newSetArgs(RoutingContext event) {
8080
private static Instant expiresAt(RoutingContext event) {
8181
return Instant.now().plusSeconds(event.<Long> get(SESSION_MAX_AGE_PARAM));
8282
}
83-
84-
record AuthorizationCodeTokensRecord(String idToken, String accessToken, String refreshToken, Long accessTokenExpiresIn,
85-
String accessTokenScope) {
86-
87-
private static AuthorizationCodeTokensRecord of(AuthorizationCodeTokens tokens) {
88-
return new AuthorizationCodeTokensRecord(tokens.getIdToken(), tokens.getAccessToken(), tokens.getRefreshToken(),
89-
tokens.getAccessTokenExpiresIn(), tokens.getAccessTokenScope());
90-
}
91-
92-
private AuthorizationCodeTokens toTokens() {
93-
return new AuthorizationCodeTokens(idToken, accessToken, refreshToken, accessTokenExpiresIn, accessTokenScope);
94-
}
95-
}
9683
}

integration-tests/keycloak-authorization/pom.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
<groupId>io.quarkus</groupId>
3131
<artifactId>quarkus-oidc</artifactId>
3232
</dependency>
33+
<dependency>
34+
<groupId>io.quarkus</groupId>
35+
<artifactId>quarkus-oidc-redis-token-state-manager</artifactId>
36+
</dependency>
3337

3438
<!-- test dependencies -->
3539
<dependency>
@@ -101,6 +105,19 @@
101105
</exclusion>
102106
</exclusions>
103107
</dependency>
108+
<dependency>
109+
<groupId>io.quarkus</groupId>
110+
<artifactId>quarkus-oidc-redis-token-state-manager-deployment</artifactId>
111+
<version>${project.version}</version>
112+
<type>pom</type>
113+
<scope>test</scope>
114+
<exclusions>
115+
<exclusion>
116+
<groupId>*</groupId>
117+
<artifactId>*</artifactId>
118+
</exclusion>
119+
</exclusions>
120+
</dependency>
104121
<dependency>
105122
<groupId>org.awaitility</groupId>
106123
<artifactId>awaitility</artifactId>

integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/PublicResource.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
package io.quarkus.it.keycloak;
22

3+
import jakarta.inject.Inject;
34
import jakarta.ws.rs.GET;
45
import jakarta.ws.rs.Path;
56

7+
import io.quarkus.redis.datasource.ReactiveRedisDataSource;
8+
69
@Path("/api")
710
public class PublicResource {
811

12+
@Inject
13+
ReactiveRedisDataSource redisDataSource;
14+
15+
@Path("/token-state-count")
16+
@GET
17+
public int tokenStateCount() {
18+
return redisDataSource.execute("DBSIZE").await().indefinitely().toInteger();
19+
}
20+
921
@GET
1022
@Path("public")
1123
public void serve() {

integration-tests/keycloak-authorization/src/test/java/io/quarkus/it/keycloak/AbstractPolicyEnforcerTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import java.net.URL;
99
import java.time.Duration;
1010

11+
import org.awaitility.Awaitility;
12+
import org.hamcrest.Matchers;
1113
import org.htmlunit.FailingHttpStatusCodeException;
1214
import org.htmlunit.SilentCssErrorHandler;
1315
import org.htmlunit.WebResponse;
@@ -19,6 +21,7 @@
1921

2022
import io.quarkus.test.common.http.TestHTTPResource;
2123
import io.quarkus.test.keycloak.client.KeycloakTestClient;
24+
import io.restassured.RestAssured;
2225
import io.vertx.core.Vertx;
2326
import io.vertx.core.json.JsonObject;
2427
import io.vertx.ext.web.client.WebClient;
@@ -69,6 +72,7 @@ public void testUserHasSuperUserRoleWebTenant() throws Exception {
6972
}
7073

7174
private void testWebAppTenantAllowed(String user) throws Exception {
75+
Awaitility.await().atMost(REQUEST_TIMEOUT).untilAsserted(() -> assertTokenStateCount(0));
7276
try (final org.htmlunit.WebClient webClient = createWebClient()) {
7377
HtmlPage page = webClient.getPage("http://localhost:8081/api-permission-webapp");
7478

@@ -88,6 +92,7 @@ private void testWebAppTenantAllowed(String user) throws Exception {
8892
assureGetPathWithCookie("//api-permission-webapp", cookie, 200, null, "Permission Resource WebApp");
8993

9094
webClient.getCookieManager().clearCookies();
95+
Awaitility.await().atMost(REQUEST_TIMEOUT).untilAsserted(() -> assertTokenStateCount(1));
9196
}
9297
}
9398

@@ -279,4 +284,11 @@ private void assurePostPath(String path, String requestBody, int expectedStatusC
279284
}
280285
}
281286

287+
private static void assertTokenStateCount(Integer expectedNumOfTokens) {
288+
RestAssured
289+
.get("/api/token-state-count")
290+
.then()
291+
.statusCode(200)
292+
.body(Matchers.is(expectedNumOfTokens.toString()));
293+
}
282294
}

0 commit comments

Comments
 (0)