Skip to content

Commit

Permalink
fix: get token endpoint from well known endpoint on every request
Browse files Browse the repository at this point in the history
  • Loading branch information
ewan-escience committed Nov 7, 2022
1 parent 998105b commit 038e75e
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 22 deletions.
6 changes: 0 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ NEXT_PUBLIC_SURFCONEXT_WELL_KNOWN_URL=https://connect.test.surfconext.nl/.well-k
NEXT_PUBLIC_SURFCONEXT_SCOPES=openid
# consumed by: frontend/utils/loginHelpers
NEXT_PUBLIC_SURFCONEXT_RESPONSE_MODE=form_post
# consumed by services: authentication
AUTH_SURFCONEXT_TOKEN_URL=https://connect.test.surfconext.nl/oidc/token

# Helmholtz AAI
# consumed by: authentication, frontend/utils/loginHelpers
Expand All @@ -96,8 +94,6 @@ NEXT_PUBLIC_HELMHOLTZAAI_WELL_KNOWN_URL=https://login-dev.helmholtz.de/oauth2/.w
NEXT_PUBLIC_HELMHOLTZAAI_SCOPES=openid+profile+email+eduperson_principal_name
# consumed by: frontend/utils/loginHelpers
NEXT_PUBLIC_HELMHOLTZAAI_RESPONSE_MODE=query
# consumed by services: authentication
AUTH_HELMHOLTZAAI_TOKEN_URL=https://login-dev.helmholtz.de/oauth2/token
# consumed by: authentication
# uncomment if you want to allow users from non-Helmholtz centres or social IdPs:
#HELMHOLTZAAI_ALLOW_EXTERNAL_USERS=true
Expand All @@ -113,8 +109,6 @@ NEXT_PUBLIC_ORCID_WELL_KNOWN_URL=https://sandbox.orcid.org/.well-known/openid-co
NEXT_PUBLIC_ORCID_SCOPES=openid
# consumed by: frontend/utils/loginHelpers
NEXT_PUBLIC_ORCID_RESPONSE_MODE=query
# consumed by services: authentication
AUTH_ORCID_TOKEN_URL=https://sandbox.orcid.org/oauth/token

# max requests to the GitHub API per run, runs 10 times per hour
# optional, comment out if not available, a default of 6 will be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public static String backendBaseUrl() {
return System.getenv("POSTGREST_URL");
}


// SURFconext
public static String surfconextRedirect() {
return System.getenv("NEXT_PUBLIC_SURFCONEXT_REDIRECT");
Expand All @@ -82,14 +83,11 @@ public static String surfconextClientSecret() {
return System.getenv("AUTH_SURFCONEXT_CLIENT_SECRET");
}

public static String surfconextTokenUrl() {
return System.getenv("AUTH_SURFCONEXT_TOKEN_URL");
}

public static String surfconextScopes() {
return System.getenv("NEXT_PUBLIC_SURFCONEXT_SCOPES");
}


// Helmholtz AAI
public static String helmholtzAaiRedirect() {
return System.getenv("NEXT_PUBLIC_HELMHOLTZAAI_REDIRECT");
Expand All @@ -107,10 +105,6 @@ public static String helmholtzAaiClientSecret() {
return System.getenv("AUTH_HELMHOLTZAAI_CLIENT_SECRET");
}

public static String helmholtzAaiTokenUrl() {
return System.getenv("AUTH_HELMHOLTZAAI_TOKEN_URL");
}

public static String helmholtzAaiScopes() {
return System.getenv("NEXT_PUBLIC_HELMHOLTZAAI_SCOPES");
}
Expand All @@ -121,6 +115,7 @@ public static boolean helmholtzAaiAllowExternalUsers() {
);
}


// ORCID
public static String orcidRedirect() {
return System.getenv("NEXT_PUBLIC_ORCID_REDIRECT");
Expand All @@ -138,10 +133,6 @@ public static String orcidClientSecret() {
return System.getenv("AUTH_ORCID_CLIENT_SECRET");
}

public static String orcidTokenUrl() {
return System.getenv("AUTH_ORCID_TOKEN_URL");
}

public static String orcidScopes() {
return System.getenv("NEXT_PUBLIC_ORCID_SCOPES");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public OpenIdInfo openidInfo() {
ClientID clientID = new ClientID(Config.helmholtzAaiClientId());
Secret clientSecret = new Secret(Config.helmholtzAaiClientSecret());
ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSecret);
URI tokenEndpoint = new URI(Config.helmholtzAaiTokenUrl());
URI tokenEndpoint = Utils.getTokenUrlFromWellKnownUrl(URI.create(Config.helmholtzAaiWellknown()));

Scope scopes = new Scope();

Expand Down Expand Up @@ -181,7 +181,7 @@ public OpenIdInfo openidInfo() {
if (organisation == null) {
// login denied by missing entitlements
// or external providers are not allowed
throw new RuntimeException("User is not allowed to login");
throw new RsdAuthenticationException("You are not allowed to login");
}

return new OpenIdInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ private Map<String, String> createForm() {

private String getTokensFromOrcidconext(Map<String, String> form) {
String body = formMapToxWwwFormUrlencoded(form);
return postForm(URI.create(Config.orcidTokenUrl()), body);
URI tokenEndpoint = Utils.getTokenUrlFromWellKnownUrl(URI.create(Config.orcidWellknown()));
return postForm(tokenEndpoint, body);
}

private String formMapToxWwwFormUrlencoded(Map<String, String> form) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ private Map<String, String> createForm() {

private String getTokensFromSurfconext(Map<String, String> form) {
String body = formMapToxWwwFormUrlencoded(form);
return postForm(URI.create(Config.surfconextTokenUrl()), body);
URI tokenEndpoint = Utils.getTokenUrlFromWellKnownUrl(URI.create(Config.surfconextWellknown()));
return postForm(tokenEndpoint, body);
}

private String formMapToxWwwFormUrlencoded(Map<String, String> form) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
package nl.esciencecenter.rsd.authentication;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class Utils {

Expand All @@ -14,4 +23,25 @@ public static String jsonElementToString(JsonElement elementToConvert) {
if (!elementToConvert.isJsonPrimitive()) return null;
return elementToConvert.getAsString();
}

public static URI getTokenUrlFromWellKnownUrl(URI wellKnownUrl) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(wellKnownUrl).build();
HttpResponse<String> response;

try {
response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}

return extractTokenUrlFromWellKnownData(response.body());
}

static URI extractTokenUrlFromWellKnownData(String jsonData) {
JsonObject dataAsObject = JsonParser.parseString(jsonData).getAsJsonObject();
String tokenUrl = dataAsObject.getAsJsonPrimitive("token_endpoint").getAsString();
return URI.create(tokenUrl);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) <e.cahen@esciencecenter.nl>
// SPDX-FileCopyrightText: 2022 Netherlands eScience Center
//
// SPDX-License-Identifier: Apache-2.0

package nl.esciencecenter.rsd.authentication;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.net.URI;

public class UtilsTest {

@Test
void givenValidWellKnownData_whenExtractingTokenEndpoint_correctResultReturned() {
String data = """
{
"token_endpoint_auth_signing_alg_values_supported": [
"RS256"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"userinfo_endpoint": "https://sandbox.orcid.org/oauth/userinfo",
"authorization_endpoint": "https://sandbox.orcid.org/oauth/authorize",
"token_endpoint": "https://sandbox.orcid.org/oauth/token",
"jwks_uri": "https://sandbox.orcid.org/oauth/jwks",
"claims_supported": [
"family_name",
"given_name",
"name",
"auth_time",
"iss",
"sub"
],
"scopes_supported": [
"openid"
],
"subject_types_supported": [
"public"
],
"response_types_supported": [
"code",
"id_token",
"id_token token"
],
"claims_parameter_supported": false,
"token_endpoint_auth_methods_supported": [
"client_secret_post"
],
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token"
],
"issuer": "https://sandbox.orcid.org"
}""";

URI tokenEndpoint = Utils.extractTokenUrlFromWellKnownData(data);

Assertions.assertEquals(URI.create("https://sandbox.orcid.org/oauth/token"), tokenEndpoint);
}

@Test
void givenInvalidJson_whenExtractingTokenEndpoint_thenExceptionThrown() {
String data = "{";

Assertions.assertThrows(RuntimeException.class, () -> Utils.extractTokenUrlFromWellKnownData(data));
}

@Test
void givenDataWithoutTokenEndpoint_whenExtractingTokenEndpoint_thenExceptionThrown() {
String data = "{\"token_endpoint\": null}";

Assertions.assertThrows(ClassCastException.class, () -> Utils.extractTokenUrlFromWellKnownData(data));
}

}

0 comments on commit 038e75e

Please sign in to comment.