From 3b6bfe2a4ebd7aad78ee8970d71809b4ae5e68e8 Mon Sep 17 00:00:00 2001 From: yagudin10 Date: Mon, 22 Aug 2022 13:23:18 +0300 Subject: [PATCH 1/2] CB-2365 reverse proxy anonymous access enabled fix --- .../service/auth/RPSessionHandler.java | 35 +++---------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java index fcb178b64b..a4a87437b4 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/RPSessionHandler.java @@ -16,31 +16,26 @@ */ package io.cloudbeaver.service.auth; -import io.cloudbeaver.DBWUserIdentity; import io.cloudbeaver.DBWebException; import io.cloudbeaver.auth.SMAuthProviderExternal; import io.cloudbeaver.auth.provider.rp.RPAuthProvider; -import io.cloudbeaver.model.session.WebAuthInfo; import io.cloudbeaver.model.session.WebSession; -import io.cloudbeaver.model.user.WebUser; +import io.cloudbeaver.model.session.WebSessionAuthProcessor; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.service.DBWSessionHandler; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.auth.SMAuthInfo; -import org.jkiss.dbeaver.model.auth.SMSession; import org.jkiss.dbeaver.model.security.SMConstants; import org.jkiss.dbeaver.model.security.SMController; import org.jkiss.dbeaver.model.security.exception.SMException; import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor; import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry; -import org.jkiss.utils.CommonUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.time.OffsetDateTime; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -70,7 +65,6 @@ public class RPSessionHandler implements DBWSessionHandler { String userName = request.getHeader(RPAuthProvider.X_USER); String roles = request.getHeader(RPAuthProvider.X_ROLE); List userRoles = roles == null ? Collections.emptyList() : List.of(roles.split("\\|")); - SMSession authSession; if (userName != null) { try { Map credentials = new HashMap<>(); @@ -79,39 +73,18 @@ public class RPSessionHandler implements DBWSessionHandler { sessionParameters.put(SMConstants.SESSION_PARAM_TRUSTED_USER_ROLES, userRoles); Map userCredentials = authProviderExternal.authExternalUser( webSession.getProgressMonitor(), sessionParameters, credentials); + String currentSmSessionId = webSession.getUser() == null ? null : webSession.getUserContext().getSmSessionId(); try { SMAuthInfo smAuthInfo = securityController.authenticate( webSession.getSessionId(), - webSession.getUserContext().getSmSessionId(), + currentSmSessionId, sessionParameters, WebSession.CB_SESSION_TYPE, authProvider.getId(), null, userCredentials); - webSession.updateSMAuthInfo(smAuthInfo); + new WebSessionAuthProcessor(webSession, smAuthInfo, false).authenticateSession(); } catch (SMException e) { log.debug("Error during user authentication", e); throw e; } - WebUser user = webSession.getUser(); - DBWUserIdentity userIdentity = authProviderExternal.getUserIdentity( - webSession.getProgressMonitor(), sessionParameters, credentials); - - if (CommonUtils.isEmpty(user.getDisplayName())) { - user.setDisplayName(userIdentity.getDisplayName()); - } - authSession = authProviderExternal.openSession( - webSession.getProgressMonitor(), - webSession, - sessionParameters, - userCredentials); - - WebAuthInfo authInfo = new WebAuthInfo( - webSession, - user, - authProvider, - userIdentity, - authSession, - OffsetDateTime.now()); - authInfo.setMessage("Authenticated with " + authProvider.getLabel() + " provider"); - webSession.addAuthInfo(authInfo); } catch (Exception e) { throw new DBWebException("Error", e); } From 819b84cc9be992d902c5b35491b13d6c4c18c9b5 Mon Sep 17 00:00:00 2001 From: yagudin10 Date: Mon, 22 Aug 2022 18:29:37 +0300 Subject: [PATCH 2/2] CB-2365 rp tests --- .../io/cloudbeaver/utils/WebTestUtils.java | 19 +++++++-- .../test/platform/AuthenticationTest.java | 42 +++++++++++++++++++ .../workspace/conf/cloudbeaver.conf | 5 ++- .../workspace/gql_scripts/activeUser.json | 4 ++ .../workspace/gql_scripts/openSession.json | 7 ++++ 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json create mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java index 24b59dbc0a..17456db347 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java @@ -29,6 +29,7 @@ import java.net.http.HttpResponse; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; +import java.util.List; import java.util.Map; public class WebTestUtils { @@ -42,12 +43,24 @@ public class WebTestUtils { public static Map doPost(String apiUrl, String input, HttpClient client) throws Exception { - HttpRequest request = HttpRequest.newBuilder() + return doPostWithHeaders(apiUrl, input, client, List.of()); + } + + public static Map doPostWithHeaders( + String apiUrl, + String input, + HttpClient client, + List headers + ) throws Exception { + HttpRequest.Builder requestBuilder = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .POST(HttpRequest.BodyPublishers.ofString(input)) - .header("Content-Type", "application/json") - .build(); + .header("Content-Type", "application/json"); + if (!headers.isEmpty()) { + requestBuilder.headers(headers.toArray(String[]::new)); + } + HttpRequest request = requestBuilder.build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java index 22adf77024..9a58c32163 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java @@ -1,15 +1,23 @@ package io.cloudbeaver.test.platform; +import io.cloudbeaver.auth.provider.rp.RPAuthProvider; import io.cloudbeaver.utils.WebTestUtils; import org.jkiss.dbeaver.model.auth.SMAuthStatus; import org.jkiss.dbeaver.model.data.json.JSONUtils; import org.junit.Assert; import org.junit.Test; +import org.mockito.Mockito; import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.util.Collections; +import java.util.List; import java.util.Map; public class AuthenticationTest { + public static final String GQL_TEMPLATE_OPEN_SESSION = "openSession.json"; + public static final String GQL_TEMPLATE_ACTIVE_USER = "activeUser.json"; + public static final String REVERSE_PROXY_TEST_USER = "reverseProxyTestUser"; @Test public void testLoginUser() throws Exception { @@ -18,4 +26,38 @@ public class AuthenticationTest { client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL); Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus")); } + + @Test + public void testReverseProxyAnonymousModeLogin() throws Exception { + HttpClient client = CEServerTestSuite.getClient(); + Map sessionInfo = openSession(client); + Assert.assertTrue(JSONUtils.getBoolean(sessionInfo, "valid")); + Map activeUser = getActiveUser(client); + Assert.assertEquals(REVERSE_PROXY_TEST_USER, JSONUtils.getString(activeUser, "userId")); + } + + private Map openSession(HttpClient client) throws Exception { + Map data = doPostQuery(client, GQL_TEMPLATE_OPEN_SESSION); + if (data != null) { + return JSONUtils.getObject(data, "session"); + } + return Collections.emptyMap(); + } + + private Map getActiveUser(HttpClient client) throws Exception { + Map data = doPostQuery(client, GQL_TEMPLATE_ACTIVE_USER); + if (data != null) { + return JSONUtils.getObject(data, "user"); + } + return Collections.emptyMap(); + } + + private Map doPostQuery(HttpClient client, String gqlScript) throws Exception { + String input = WebTestUtils.readScriptTemplate(gqlScript, CEServerTestSuite.getScriptsPath()); + List headers = List.of(RPAuthProvider.X_USER, REVERSE_PROXY_TEST_USER, RPAuthProvider.X_ROLE, "user"); + Map map = WebTestUtils.doPostWithHeaders(CEServerTestSuite.GQL_API_URL, input, client, headers); + return JSONUtils.getObjectOrNull(map, "data"); + } + + } diff --git a/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf b/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf index e6d24f8063..f56cacd670 100644 --- a/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf +++ b/server/test/io.cloudbeaver.test.platform/workspace/conf/cloudbeaver.conf @@ -1,6 +1,7 @@ { server: { serverPort: "${CLOUDBEAVER_TEST_PORT:18978}", + serverName: "CloudBeaver CE Test Server", workspaceLocation: "workspace", contentRoot: "workspace/web", @@ -36,8 +37,10 @@ anonymousAccessEnabled: true, anonymousUserRole: "user", supportsCustomConnections: true, + enableReverseProxyAuth: true, enabledAuthProviders: [ - "local" + "local", + "reverseProxy" ], enabledFeatures: [ diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json new file mode 100644 index 0000000000..97b079675a --- /dev/null +++ b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json @@ -0,0 +1,4 @@ +{ + "query": "\n query activeUser {\n user: activeUser {\n userId\n }\n}\n ", + "operationName": "activeUser" +} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json new file mode 100644 index 0000000000..eff24dcf81 --- /dev/null +++ b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json @@ -0,0 +1,7 @@ +{ + "query": "\n mutation openSession($defaultLocale: String) {\n session: openSession(defaultLocale: $defaultLocale) {\n valid\n }\n}\n ", + "variables": { + "defaultLocale": "en" + }, + "operationName": "openSession" +} \ No newline at end of file