From 8c009b9a8dc6cd231655214d5cf45881a6ca2fdd Mon Sep 17 00:00:00 2001 From: Mauro Mugnaini Date: Tue, 30 Apr 2024 12:55:04 +0200 Subject: [PATCH] Renamed method `isSignatureValid()` to `isValid()` since it tests also other aspects (exipration, not before, etc...). --- .../gcube/common/keycloak/KeycloakClient.java | 4 +++- .../common/keycloak/model/ModelUtils.java | 21 +++++++++++++------ .../model/PublishedRealmRepresentation.java | 7 ++++++- .../common/keycloak/TestKeycloakClient.java | 6 ++---- .../gcube/common/keycloak/TestModelUtils.java | 4 ++-- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/gcube/common/keycloak/KeycloakClient.java b/src/main/java/org/gcube/common/keycloak/KeycloakClient.java index a3aad44..5f2b4f3 100644 --- a/src/main/java/org/gcube/common/keycloak/KeycloakClient.java +++ b/src/main/java/org/gcube/common/keycloak/KeycloakClient.java @@ -4,6 +4,7 @@ import java.net.URL; import java.util.List; import java.util.Map; +import org.gcube.com.fasterxml.jackson.annotation.JsonProperty; import org.gcube.common.keycloak.model.PublishedRealmRepresentation; import org.gcube.common.keycloak.model.TokenIntrospectionResponse; import org.gcube.common.keycloak.model.TokenResponse; @@ -76,7 +77,8 @@ public interface KeycloakClient { URL getAvatarEndpointURL(URL realmBaseURL) throws KeycloakClientException; /** - * Get the realm info setup + * Get the realm info setup (RSA public_key, token-service URL, + * account-service URL and tokens-not-before setting) * * @param realmURL the realm URL * @return the configured realm info diff --git a/src/main/java/org/gcube/common/keycloak/model/ModelUtils.java b/src/main/java/org/gcube/common/keycloak/model/ModelUtils.java index 6d66904..820d39c 100644 --- a/src/main/java/org/gcube/common/keycloak/model/ModelUtils.java +++ b/src/main/java/org/gcube/common/keycloak/model/ModelUtils.java @@ -48,10 +48,19 @@ public class ModelUtils { } } - public static RSAPublicKey createRSAPublicKey(String publicKeyPem) { + /** + * Creates and {@link RSAPublicKey} instance from its string PEM representation + * + * @param publicKeyPem the public key PEM string + * @return the RSA public key + * @throws Exception if it's not possbile to create the RSA public key from the PEM string + */ + public static RSAPublicKey createRSAPublicKey(String publicKeyPem) throws Exception { try { - String publicKey = publicKeyPem.replaceFirst("-----BEGIN .+-----\n", ""); - publicKey = publicKey.replaceFirst("-----END .+-----", ""); + String publicKey = publicKeyPem.replaceFirst("-----BEGIN (.*)-----\n", ""); + publicKey = publicKey.replaceFirst("-----END (.*)-----", ""); + publicKey = publicKey.replaceAll("\r\n", ""); + publicKey = publicKey.replaceAll("\n", ""); byte[] encoded = Base64.getDecoder().decode(publicKey); KeyFactory kf = KeyFactory.getInstance("RSA"); @@ -62,14 +71,14 @@ public class ModelUtils { } /** - * Verifies the token's digital signature + * Verifies the token validity * * @param token the base64 JWT token string * @param publicKey the realm's public key on server - * @return true if the signature is verified, false otherwise + * @return true if the token is valid, false otherwise * @throws RuntimeException if an error occurs constructing the digital signature verifier */ - public static boolean isSignatureValid(String token, RSAPublicKey publicKey) throws RuntimeException { + public static boolean isValid(String token, RSAPublicKey publicKey) throws RuntimeException { JWTVerifier verifier = null; try { Algorithm algorithm = Algorithm.RSA256(publicKey, null); diff --git a/src/main/java/org/gcube/common/keycloak/model/PublishedRealmRepresentation.java b/src/main/java/org/gcube/common/keycloak/model/PublishedRealmRepresentation.java index c86b862..652ad54 100644 --- a/src/main/java/org/gcube/common/keycloak/model/PublishedRealmRepresentation.java +++ b/src/main/java/org/gcube/common/keycloak/model/PublishedRealmRepresentation.java @@ -26,6 +26,7 @@ import org.gcube.com.fasterxml.jackson.annotation.JsonProperty; * @author (modified by) Mauro Mugnaini */ public class PublishedRealmRepresentation { + protected String realm; @JsonProperty("public_key") @@ -65,7 +66,11 @@ public class PublishedRealmRepresentation { if (publicKey != null) return publicKey; if (publicKeyPem != null) { - publicKey = ModelUtils.createRSAPublicKey(publicKeyPem); + try { + publicKey = ModelUtils.createRSAPublicKey(publicKeyPem); + } catch (Exception e) { + e.printStackTrace(); + } } return publicKey; } diff --git a/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java b/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java index dbf7145..480d7cc 100644 --- a/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java +++ b/src/test/java/org/gcube/common/keycloak/TestKeycloakClient.java @@ -133,8 +133,6 @@ public class TestKeycloakClient { logger.info("*** [1.0] Realm info public key PEM: {}", realmInfo.getPublicKeyPem()); logger.info("*** [1.0] Realm info public key: {}", realmInfo.getPublicKey()); - // TestModels.checkTokenResponse(oidcTR); - // TestModels.checkAccessToken(ModelUtils.getAccessTokenFrom(oidcTR), "service-account-" + CLIENT_ID, false); } @Test @@ -149,8 +147,8 @@ public class TestKeycloakClient { TokenResponse oidcTR = client.queryOIDCToken(DEV_ROOT_CONTEXT, CLIENT_ID, CLIENT_SECRET); logger.info("*** [1.0] OIDC access token: {}", oidcTR.getAccessToken()); - Assert.assertTrue("Access token digital signature is not valid", - ModelUtils.isSignatureValid(oidcTR.getAccessToken(), realmInfo.getPublicKey())); + Assert.assertTrue("Access token is not valid", + ModelUtils.isValid(oidcTR.getAccessToken(), realmInfo.getPublicKey())); } @Test diff --git a/src/test/java/org/gcube/common/keycloak/TestModelUtils.java b/src/test/java/org/gcube/common/keycloak/TestModelUtils.java index 4a8ea2b..37f5bf0 100644 --- a/src/test/java/org/gcube/common/keycloak/TestModelUtils.java +++ b/src/test/java/org/gcube/common/keycloak/TestModelUtils.java @@ -39,8 +39,8 @@ public class TestModelUtils { TokenResponse.class); // Valid signature - Assert.assertFalse("Token signature is valid", ModelUtils.isSignatureValid(tr.getAccessToken(), - ModelUtils.createRSAPublicKey( + Assert.assertFalse("Token signature is valid", + ModelUtils.isValid(tr.getAccessToken(), ModelUtils.createRSAPublicKey( new String(Files.readAllBytes(Paths.get("src/test/resources/rsa-public-key.pem")))))); }