aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel <djr2468@gmail.com>2023-04-05 17:40:11 +0100
committerDaniel <djr2468@gmail.com>2023-04-05 17:40:11 +0100
commit9ab4a6e303c0e8a4997252b4c6a8b2dd601d73af (patch)
tree62a233014ecfa16af322a53e9ca04e4b6b0d1ad3
parent0f092e6aac198bd7244f8011a61bb22ab56174cf (diff)
downloadtrackermap-server-9ab4a6e303c0e8a4997252b4c6a8b2dd601d73af.tar.gz
trackermap-server-9ab4a6e303c0e8a4997252b4c6a8b2dd601d73af.tar.bz2
trackermap-server-9ab4a6e303c0e8a4997252b4c6a8b2dd601d73af.zip
Implement OpenID auto discovery
-rw-r--r--src/main/java/org/traccar/config/Keys.java15
-rw-r--r--src/main/java/org/traccar/database/OpenIdProvider.java44
2 files changed, 53 insertions, 6 deletions
diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java
index 3ff423ad1..3ed6c6026 100644
--- a/src/main/java/org/traccar/config/Keys.java
+++ b/src/main/java/org/traccar/config/Keys.java
@@ -637,10 +637,19 @@ public final class Keys {
List.of(KeyType.CONFIG));
/**
+ * OpenID Connect Issuer (Base) URL.
+ * This is used to automatically configure the authorization, token and user info URLs if
+ * they are not provided.
+ */
+ public static final ConfigKey<String> OPENID_ISSUERURL = new StringConfigKey(
+ "openid.issuerUrl",
+ List.of(KeyType.CONFIG));
+
+ /**
* OpenID Connect Authorization URL.
* This can usually be found in the documentation of your identity provider or by using the well-known
* configuration endpoint, eg. https://auth.example.com//.well-known/openid-configuration
- * Required to enable SSO.
+ * Required to enable SSO if openid.issuerUrl is not set.
*/
public static final ConfigKey<String> OPENID_AUTHURL = new StringConfigKey(
"openid.authUrl",
@@ -648,7 +657,7 @@ public final class Keys {
/**
* OpenID Connect Token URL.
* This can be found in the same ways at openid.authUrl.
- * Required to enable SSO.
+ * Required to enable SSO if openid.issuerUrl is not set.
*/
public static final ConfigKey<String> OPENID_TOKENURL = new StringConfigKey(
"openid.tokenUrl",
@@ -657,7 +666,7 @@ public final class Keys {
/**
* OpenID Connect User Info URL.
* This can be found in the same ways at openid.authUrl.
- * Required to enable SSO.
+ * Required to enable SSO if openid.issuerUrl is not set.
*/
public static final ConfigKey<String> OPENID_USERINFOURL = new StringConfigKey(
"openid.userInfoUrl",
diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java
index 537319b31..2b0f9d290 100644
--- a/src/main/java/org/traccar/database/OpenIdProvider.java
+++ b/src/main/java/org/traccar/database/OpenIdProvider.java
@@ -26,9 +26,16 @@ import org.traccar.helper.ServletHelper;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse.BodyHandlers;
import java.security.GeneralSecurityException;
+import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,12 +89,43 @@ public class OpenIdProvider {
try {
callbackUrl = new URI(config.getString(Keys.WEB_URL, "") + "/api/session/openid/callback");
- authUrl = new URI(config.getString(Keys.OPENID_AUTHURL, ""));
- tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL, ""));
- userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL, ""));
baseUrl = new URI(config.getString(Keys.WEB_URL, ""));
+
+ if (
+ config.hasKey(Keys.OPENID_ISSUERURL)
+ && (
+ !config.hasKey(Keys.OPENID_AUTHURL)
+ || !config.hasKey(Keys.OPENID_TOKENURL)
+ || !config.hasKey(Keys.OPENID_USERINFOURL))
+ ) {
+ HttpClient httpClient = HttpClient.newHttpClient();
+
+ HttpRequest httpRequest = HttpRequest.newBuilder(
+ URI.create(
+ config.getString(Keys.OPENID_ISSUERURL) + "/.well-known/openid-configuration")
+ )
+ .header("accept", "application/json")
+ .build();
+
+ String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body();
+
+ Map<String, Object> discoveryMap = new ObjectMapper().readValue(
+ httpResponse, new TypeReference<Map<String, Object>>() { });
+
+ authUrl = new URI(discoveryMap.get("authorization_endpoint").toString());
+ tokenUrl = new URI(discoveryMap.get("token_endpoint").toString());
+ userInfoUrl = new URI(discoveryMap.get("userinfo_endpoint").toString());
+
+ LOGGER.info("OpenID Connect auto discovery successful");
+ } else {
+ authUrl = new URI(config.getString(Keys.OPENID_AUTHURL));
+ tokenUrl = new URI(config.getString(Keys.OPENID_TOKENURL));
+ userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFOURL));
+ }
} catch (URISyntaxException error) {
LOGGER.error("Invalid URIs provided in OpenID configuration");
+ } catch (InterruptedException | IOException error) {
+ LOGGER.error("OpenID Connect auto discovery failed");
}
adminGroup = config.getString(Keys.OPENID_ADMINGROUP);