Added methods for `token` and `introspect` endpoint construction starting from realm's base URL and related tests

This commit is contained in:
Mauro Mugnaini 2022-06-10 13:48:48 +02:00
parent 460b080fcd
commit 7ae6a7dcd8
3 changed files with 109 additions and 11 deletions

View File

@ -28,23 +28,64 @@ import org.gcube.common.gxrest.response.inbound.GXInboundResponse;
import org.gcube.common.keycloak.model.ModelUtils;
import org.gcube.common.keycloak.model.TokenIntrospectionResponse;
import org.gcube.common.keycloak.model.TokenResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultKeycloakClient implements KeycloakClient {
protected static Logger logger = LoggerFactory.getLogger(KeycloakClient.class);
@Override
public URL getTokenEndpointURL(URL realmBaseURL) throws KeycloakClientException {
logger.debug("Constructing token endpoint URL starting from base URL: {}", realmBaseURL);
try {
URL tokenURL = null;
if (realmBaseURL.getPath().endsWith("/")) {
tokenURL = new URL(realmBaseURL, OPEN_ID_URI_PATH + "/" + TOKEN_URI_PATH);
} else {
tokenURL = new URL(realmBaseURL.toString() + "/" + OPEN_ID_URI_PATH + "/" + TOKEN_URI_PATH);
}
logger.debug("Constructed token URL is: {}", tokenURL);
return tokenURL;
} catch (MalformedURLException e) {
throw new KeycloakClientException("Cannot constructs toke URL from base URL: " + realmBaseURL, e);
}
}
@Override
public URL getIntrospectionEndpointURL(URL realmBaseURL) throws KeycloakClientException {
logger.debug("Constructing introspection URL starting from base URL: {}", realmBaseURL);
try {
URL tokenURL = null;
if (realmBaseURL.getPath().endsWith("/")) {
tokenURL = new URL(realmBaseURL,
OPEN_ID_URI_PATH + "/" + TOKEN_URI_PATH + "/" + TOKEN_INTROSPECT_URI_PATH);
} else {
tokenURL = new URL(realmBaseURL.toString() + "/" + OPEN_ID_URI_PATH + "/" + TOKEN_URI_PATH + "/"
+ TOKEN_INTROSPECT_URI_PATH);
}
logger.debug("Constructed introspection URL is: {}", tokenURL);
return tokenURL;
} catch (MalformedURLException e) {
throw new KeycloakClientException("Cannot constructs toke URL from base URL: " + realmBaseURL, e);
}
}
@Override
public URL computeIntrospectionEndpointURL(URL tokenEndpointURL) throws KeycloakClientException {
logger.debug("Computing introspection URL starting from token endpoint URL: {}", tokenEndpointURL);
logger.debug("Computing introspection endpoint URL starting from token endpoint URL: {}", tokenEndpointURL);
try {
URL introspectionURL = null;
if (tokenEndpointURL.getPath().endsWith("token/")) {
introspectionURL = new URL(tokenEndpointURL, "introspect");
if (tokenEndpointURL.getPath().endsWith(TOKEN_URI_PATH + "/")) {
introspectionURL = new URL(tokenEndpointURL, TOKEN_INTROSPECT_URI_PATH);
} else {
introspectionURL = new URL(tokenEndpointURL, "token/introspect");
introspectionURL = new URL(tokenEndpointURL, TOKEN_URI_PATH + "/" + TOKEN_INTROSPECT_URI_PATH);
}
logger.debug("Computed introspection URL is: {}", introspectionURL);
return introspectionURL;
} catch (MalformedURLException e) {
throw new KeycloakClientException("Cannot create introspection URL from token URL: " + tokenEndpointURL, e);
throw new KeycloakClientException("Cannot compute introspection URL from token URL: " + tokenEndpointURL,
e);
}
}

View File

@ -5,17 +5,33 @@ import java.util.List;
import org.gcube.common.keycloak.model.TokenIntrospectionResponse;
import org.gcube.common.keycloak.model.TokenResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface KeycloakClient {
Logger logger = LoggerFactory.getLogger(KeycloakClient.class);
public static final String OPEN_ID_URI_PATH = "protocol/openid-connect";
public static final String TOKEN_URI_PATH = "token";
public static final String TOKEN_INTROSPECT_URI_PATH = "introspect";
/**
* Constructs the Keycloak <code>token</code> endpoint {@link URL} from the realm's base URL.
*
* @return the Keycloak <code>token</code> endpoint URL
* @throws KeycloakClientException if something goes wrong discovering the endpoint URL
*/
URL getTokenEndpointURL(URL realmBaseURL) throws KeycloakClientException;
/**
* Constructs the Keycloak <code>introspection</code> endpoint {@link URL} from the realm's base URL.
*
* @return the Keycloak <code>introspection</code> endpoint URL
* @throws KeycloakClientException if something goes wrong discovering the endpoint URL
*/
URL getIntrospectionEndpointURL(URL realmBaseURL) throws KeycloakClientException;
/**
* Compute the keycloak <code>introspection</code> endpoint {@link URL} starting from the provided token endpoint.
*
* @return the keycloak <code>introspection</code> endpoint URL in the current scope
* @return the keycloak <code>introspection</code> endpoint URL
* @throws KeycloakClientException if something goes wrong discovering the endpoint URL
*/
URL computeIntrospectionEndpointURL(URL tokenEndpointURL) throws KeycloakClientException;

View File

@ -19,7 +19,8 @@ public class TestKeycloakClient {
protected static final Logger logger = LoggerFactory.getLogger(TestKeycloakClient.class);
protected static final String DEV_TOKEN_ENDPOINT = "https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token";
protected static final String DEV_BASE_URL = "https://accounts.dev.d4science.org/auth/realms/d4science";
protected static final String DEV_TOKEN_ENDPOINT = DEV_BASE_URL + "/protocol/openid-connect/token";
protected static final String DEV_INTROSPECTION_ENDPOINT = DEV_TOKEN_ENDPOINT + "/introspect";
protected static final String CLIENT_ID = "keycloak-client-unit-test";
@ -39,6 +40,46 @@ public class TestKeycloakClient {
public void tearDown() throws Exception {
}
@Test
public void test00TokenEndpointConstruction() throws Exception {
logger.info("*** [0.0] Start testing Keycloak token endpoint construction from base URL...");
URL url = KeycloakClientFactory.newInstance().getTokenEndpointURL(new URL(DEV_BASE_URL));
Assert.assertNotNull(url);
Assert.assertTrue(url.getProtocol().equals("https"));
Assert.assertEquals(new URL(DEV_TOKEN_ENDPOINT), url);
logger.info("Constructed URL is: {}", url);
}
@Test
public void test00ATokenEndpointConstructionWithTrailingSlash() throws Exception {
logger.info("*** [0.0] Start testing Keycloak token endpoint construction from base URL with trailing slash...");
URL url = KeycloakClientFactory.newInstance().getTokenEndpointURL(new URL(DEV_BASE_URL + "/"));
Assert.assertNotNull(url);
Assert.assertTrue(url.getProtocol().equals("https"));
Assert.assertEquals(new URL(DEV_TOKEN_ENDPOINT), url);
logger.info("Constructed URL is: {}", url);
}
@Test
public void test01IntrospectionEndpointConstruction() throws Exception {
logger.info("*** [0.0] Start testing Keycloak introspection endpoint construction from base URL...");
URL url = KeycloakClientFactory.newInstance().getIntrospectionEndpointURL(new URL(DEV_BASE_URL));
Assert.assertNotNull(url);
Assert.assertTrue(url.getProtocol().equals("https"));
Assert.assertEquals(new URL(DEV_INTROSPECTION_ENDPOINT), url);
logger.info("Constructed URL is: {}", url);
}
@Test
public void test01AIntrospectionEndpointConstructionWithTrailingSlash() throws Exception {
logger.info("*** [0.0] Start testing Keycloak introspection endpoint construction from base URL with trailing slash...");
URL url = KeycloakClientFactory.newInstance().getIntrospectionEndpointURL(new URL(DEV_BASE_URL + "/"));
Assert.assertNotNull(url);
Assert.assertTrue(url.getProtocol().equals("https"));
Assert.assertEquals(new URL(DEV_INTROSPECTION_ENDPOINT), url);
logger.info("Constructed URL is: {}", url);
}
@Test
public void test02IntrospectEndpointCompute() throws Exception {
logger.info("*** [0.2] Start testing Keycloak userinfo endpoint computed from provided URL...");
@ -46,7 +87,7 @@ public class TestKeycloakClient {
Assert.assertNotNull(url);
Assert.assertTrue(url.getProtocol().equals("https"));
Assert.assertEquals(new URL(DEV_INTROSPECTION_ENDPOINT), url);
logger.info("Discovered URL is: {}", url);
logger.info("Computed URL is: {}", url);
}
@Test