Skip to content

Commit

Permalink
Update OIDC DB TokenStateManager to keep access token expires_in
Browse files Browse the repository at this point in the history
  • Loading branch information
sberyozkin committed Jan 14, 2025
1 parent 54619a8 commit 185e327
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,29 @@ SyntheticBeanBuildItem produceDbTokenStateManagerBean(OidcDbTokenStateManagerRec
final String[] queryParamPlaceholders;
switch (sqlClientBuildItem.reactiveClient) {
case REACTIVE_PG_CLIENT:
queryParamPlaceholders = new String[] { "$1", "$2", "$3", "$4", "$5" };
queryParamPlaceholders = new String[] { "$1", "$2", "$3", "$4", "$5", "$6" };
break;
case REACTIVE_MSSQL_CLIENT:
queryParamPlaceholders = new String[] { "@p1", "@p2", "@p3", "@p4", "@p5" };
queryParamPlaceholders = new String[] { "@p1", "@p2", "@p3", "@p4", "@p5", "@p6" };
break;
case REACTIVE_MYSQL_CLIENT:
case REACTIVE_DB2_CLIENT:
case REACTIVE_ORACLE_CLIENT:
queryParamPlaceholders = new String[] { "?", "?", "?", "?", "?" };
queryParamPlaceholders = new String[] { "?", "?", "?", "?", "?", "?" };
break;
default:
throw new RuntimeException("Unknown Reactive Sql Client " + sqlClientBuildItem.reactiveClient);
}
String deleteStatement = format("DELETE FROM oidc_db_token_state_manager WHERE id = %s", queryParamPlaceholders[0]);
String getQuery = format("SELECT id_token, access_token, refresh_token FROM oidc_db_token_state_manager WHERE " +
"id = %s", queryParamPlaceholders[0]);
String getQuery = format(
"SELECT id_token, access_token, refresh_token, access_token_expires_in FROM oidc_db_token_state_manager WHERE "
+
"id = %s",
queryParamPlaceholders[0]);
String insertStatement = format("INSERT INTO oidc_db_token_state_manager (id_token, access_token, refresh_token," +
" expires_in, id) VALUES (%s, %s, %s, %s, %s)", queryParamPlaceholders[0], queryParamPlaceholders[1],
queryParamPlaceholders[2], queryParamPlaceholders[3], queryParamPlaceholders[4]);
" access_token_expires_in, expires_in, id) VALUES (%s, %s, %s, %s, %s, %s)", queryParamPlaceholders[0],
queryParamPlaceholders[1],
queryParamPlaceholders[2], queryParamPlaceholders[3], queryParamPlaceholders[4], queryParamPlaceholders[5]);
return SyntheticBeanBuildItem
.configure(OidcDbTokenStateManager.class)
.alternative(true)
Expand Down Expand Up @@ -114,6 +118,7 @@ SyntheticBeanBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuild
"id_token VARCHAR, " +
"access_token VARCHAR, " +
"refresh_token VARCHAR, " +
"access_token_expires_in BIGINT, " +
"expires_in BIGINT NOT NULL)";
supportsIfTableNotExists = true;
break;
Expand All @@ -123,6 +128,7 @@ SyntheticBeanBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuild
+ "id_token VARCHAR(5000) NULL, "
+ "access_token VARCHAR(5000) NULL, "
+ "refresh_token VARCHAR(5000) NULL, "
+ "access_token_expires_in BIGINT NULL, "
+ "expires_in BIGINT NOT NULL, "
+ "PRIMARY KEY (id))";
supportsIfTableNotExists = true;
Expand All @@ -133,6 +139,7 @@ SyntheticBeanBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuild
+ "id_token NVARCHAR(MAX), "
+ "access_token NVARCHAR(MAX), "
+ "refresh_token NVARCHAR(MAX), "
+ "access_token_expires_in BIGINT, "
+ "expires_in BIGINT NOT NULL)";
supportsIfTableNotExists = false;
break;
Expand All @@ -142,6 +149,7 @@ SyntheticBeanBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuild
+ "id_token VARCHAR(4000), "
+ "access_token VARCHAR(4000), "
+ "refresh_token VARCHAR(4000), "
+ "access_token_expires_in BIGINT, "
+ "expires_in BIGINT NOT NULL)";
supportsIfTableNotExists = false;
break;
Expand All @@ -151,6 +159,7 @@ SyntheticBeanBuildItem createDbTokenStateInitializerProps(ReactiveSqlClientBuild
+ "id_token VARCHAR2(4000), "
+ "access_token VARCHAR2(4000), "
+ "refresh_token VARCHAR2(4000), "
+ "access_token_expires_in NUMBER, "
+ "expires_in NUMBER NOT NULL, "
+ "PRIMARY KEY (id))";
supportsIfTableNotExists = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ public void testCodeFlow() throws IOException {

textPage = loginForm.getButtonByName("login").click();

assertEquals("alice", textPage.getContent());
assertEquals("alice, access token: true, access_token_expires_in: true, refresh_token: true",
textPage.getContent());

assertTokenStateCount(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public class OidcDbTokenStateManagerEntity {
@Column(name = "access_token", length = 4000)
String accessToken;

@Column(name = "access_token_expires_in")
Long accessTokenExpiresIn;

@Column(name = "expires_in")
Long expiresIn;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void create(Long numOfTokens) {
token.idToken = "ID TOKEN " + i;
token.accessToken = "ACCESS TOKEN " + i;
token.refreshToken = "REFRESH TOKEN " + i;
token.accessTokenExpiresIn = 10L + i;
token.expiresIn = expiresIn5Sec;
token.id = UUID.randomUUID().toString() + Instant.now().getEpochSecond();
em.persist(token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

import org.eclipse.microprofile.jwt.JsonWebToken;

import io.quarkus.oidc.AuthorizationCodeTokens;
import io.quarkus.oidc.IdToken;
import io.quarkus.security.Authenticated;
import io.vertx.ext.web.RoutingContext;

@Path("/protected")
@Authenticated
Expand All @@ -17,9 +19,17 @@ public class ProtectedResource {
@IdToken
JsonWebToken idToken;

@Inject
RoutingContext context;

@GET
public String getName() {
return idToken.getName();
AuthorizationCodeTokens tokens = context.get(AuthorizationCodeTokens.class.getName());
return idToken.getName()
+ ", access token: " + (tokens.getAccessToken() != null)
+ ", access_token_expires_in: " + (tokens.getAccessTokenExpiresIn() != null)
+ ", refresh_token: " + (tokens.getRefreshToken() != null);

}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public class OidcDbTokenStateManager implements TokenStateManager {
private static final Logger LOG = Logger.getLogger(OidcDbTokenStateManager.class);
private static final String TOKEN_STATE_INSERT_FAILED = "Failed to insert token state into database";
private static final String FAILED_TO_ACQUIRE_TOKEN = "Failed to acquire authorization code tokens";

private static final String ID_TOKEN_COLUMN = "id_token";
private static final String ACCESS_TOKEN_COLUMN = "access_token";
private static final String ACCESS_TOKEN_EXPIRES_IN_COLUMN = "access_token_expires_in";
private static final String REFRESH_TOKEN_COLUMN = "refresh_token";

private final String insertStatement;
private final String deleteStatement;
private final String getQuery;
Expand Down Expand Up @@ -54,7 +60,8 @@ public Uni<String> createTokenState(RoutingContext event, OidcTenantConfig oidcC
.preparedQuery(insertStatement)
.execute(
Tuple.of(tokens.getIdToken(), tokens.getAccessToken(),
tokens.getRefreshToken(), expiresIn(event), id)))
tokens.getRefreshToken(), tokens.getAccessTokenExpiresIn(),
expiresIn(event), id)))
.toCompletionStage())
.onFailure().transform(new Function<Throwable, Throwable>() {
@Override
Expand Down Expand Up @@ -100,9 +107,10 @@ public Uni<? extends AuthorizationCodeTokens> apply(RowSet<Row> rows) {
return Uni
.createFrom()
.item(new AuthorizationCodeTokens(
firstRow.getString("id_token"),
firstRow.getString("access_token"),
firstRow.getString("refresh_token")));
firstRow.getString(ID_TOKEN_COLUMN),
firstRow.getString(ACCESS_TOKEN_COLUMN),
firstRow.getString(REFRESH_TOKEN_COLUMN),
firstRow.getLong(ACCESS_TOKEN_EXPIRES_IN_COLUMN)));
}
}
return Uni.createFrom().failure(new AuthenticationCompletionException(FAILED_TO_ACQUIRE_TOKEN));
Expand Down

0 comments on commit 185e327

Please sign in to comment.