aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/database/OpenIdProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/database/OpenIdProvider.java')
-rw-r--r--src/main/java/org/traccar/database/OpenIdProvider.java67
1 files changed, 46 insertions, 21 deletions
diff --git a/src/main/java/org/traccar/database/OpenIdProvider.java b/src/main/java/org/traccar/database/OpenIdProvider.java
index 537319b31..d0ec4e98d 100644
--- a/src/main/java/org/traccar/database/OpenIdProvider.java
+++ b/src/main/java/org/traccar/database/OpenIdProvider.java
@@ -22,16 +22,22 @@ import org.traccar.api.security.LoginService;
import org.traccar.model.User;
import org.traccar.storage.StorageException;
import org.traccar.helper.LogAction;
-import org.traccar.helper.ServletHelper;
+import org.traccar.helper.WebHelper;
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.List;
+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;
import com.nimbusds.oauth2.sdk.http.HTTPResponse;
import com.nimbusds.oauth2.sdk.AuthorizationCode;
@@ -54,12 +60,9 @@ import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser;
import com.nimbusds.openid.connect.sdk.UserInfoResponse;
import com.nimbusds.openid.connect.sdk.UserInfoRequest;
import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
-
import com.nimbusds.openid.connect.sdk.claims.UserInfo;
public class OpenIdProvider {
- private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdProvider.class);
-
private final Boolean force;
private final ClientID clientId;
private final ClientAuthentication clientAuth;
@@ -69,28 +72,45 @@ public class OpenIdProvider {
private URI userInfoUrl;
private URI baseUrl;
private final String adminGroup;
+ private final String allowGroup;
private LoginService loginService;
@Inject
- public OpenIdProvider(Config config, LoginService loginService) {
+ public OpenIdProvider(
+ Config config, LoginService loginService, HttpClient httpClient, ObjectMapper objectMapper
+ ) throws InterruptedException, IOException, URISyntaxException {
this.loginService = loginService;
force = config.getBoolean(Keys.OPENID_FORCE);
- clientId = new ClientID(config.getString(Keys.OPENID_CLIENTID));
- clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENTSECRET)));
-
- 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, ""));
- } catch (URISyntaxException error) {
- LOGGER.error("Invalid URIs provided in OpenID configuration");
+ clientId = new ClientID(config.getString(Keys.OPENID_CLIENT_ID));
+ clientAuth = new ClientSecretBasic(clientId, new Secret(config.getString(Keys.OPENID_CLIENT_SECRET)));
+
+ baseUrl = new URI(WebHelper.retrieveWebUrl(config));
+ callbackUrl = new URI(WebHelper.retrieveWebUrl(config) + "/api/session/openid/callback");
+
+ if (config.hasKey(Keys.OPENID_ISSUER_URL)) {
+ HttpRequest httpRequest = HttpRequest.newBuilder(
+ URI.create(config.getString(Keys.OPENID_ISSUER_URL) + "/.well-known/openid-configuration"))
+ .header("Accept", "application/json")
+ .build();
+
+ String httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString()).body();
+
+ Map<String, Object> discoveryMap = objectMapper.readValue(
+ httpResponse, new TypeReference<Map<String, Object>>() { });
+
+ authUrl = new URI((String) discoveryMap.get("authorization_endpoint"));
+ tokenUrl = new URI((String) discoveryMap.get("token_endpoint"));
+ userInfoUrl = new URI((String) discoveryMap.get("userinfo_endpoint"));
+ } else {
+ authUrl = new URI(config.getString(Keys.OPENID_AUTH_URL));
+ tokenUrl = new URI(config.getString(Keys.OPENID_TOKEN_URL));
+ userInfoUrl = new URI(config.getString(Keys.OPENID_USERINFO_URL));
}
- adminGroup = config.getString(Keys.OPENID_ADMINGROUP);
+ adminGroup = config.getString(Keys.OPENID_ADMIN_GROUP);
+ allowGroup = config.getString(Keys.OPENID_ALLOW_GROUP);
}
public URI createAuthUri() {
@@ -162,12 +182,17 @@ public class OpenIdProvider {
UserInfo userInfo = getUserInfo(bearerToken);
- Boolean administrator = adminGroup != null && userInfo.getStringListClaim("groups").contains(adminGroup);
+ List<String> userGroups = userInfo.getStringListClaim("groups");
+ Boolean administrator = adminGroup != null && userGroups.contains(adminGroup);
+
+ if (!(administrator || allowGroup == null || userGroups.contains(allowGroup))) {
+ throw new GeneralSecurityException("Your OpenID Groups do not permit access to Traccar.");
+ }
User user = loginService.login(userInfo.getEmailAddress(), userInfo.getName(), administrator);
request.getSession().setAttribute(SessionResource.USER_ID_KEY, user.getId());
- LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request));
+ LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request));
return baseUrl;
}