mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge pull request #1062 from dbeaver/fix/CB-2365
CB-2365 reverse proxy anonymous access enabled fix
This commit is contained in:
@@ -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<String, Object> doPost(String apiUrl, String input, HttpClient client) throws Exception {
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
return doPostWithHeaders(apiUrl, input, client, List.of());
|
||||
}
|
||||
|
||||
public static Map<String, Object> doPostWithHeaders(
|
||||
String apiUrl,
|
||||
String input,
|
||||
HttpClient client,
|
||||
List<String> 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<String> response = client.send(request,
|
||||
HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
|
||||
+4
-31
@@ -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<String> userRoles = roles == null ? Collections.emptyList() : List.of(roles.split("\\|"));
|
||||
SMSession authSession;
|
||||
if (userName != null) {
|
||||
try {
|
||||
Map<String, Object> credentials = new HashMap<>();
|
||||
@@ -79,39 +73,18 @@ public class RPSessionHandler implements DBWSessionHandler {
|
||||
sessionParameters.put(SMConstants.SESSION_PARAM_TRUSTED_USER_ROLES, userRoles);
|
||||
Map<String, Object> 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);
|
||||
}
|
||||
|
||||
+42
@@ -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<String, Object> sessionInfo = openSession(client);
|
||||
Assert.assertTrue(JSONUtils.getBoolean(sessionInfo, "valid"));
|
||||
Map<String, Object> activeUser = getActiveUser(client);
|
||||
Assert.assertEquals(REVERSE_PROXY_TEST_USER, JSONUtils.getString(activeUser, "userId"));
|
||||
}
|
||||
|
||||
private Map<String, Object> openSession(HttpClient client) throws Exception {
|
||||
Map<String, Object> data = doPostQuery(client, GQL_TEMPLATE_OPEN_SESSION);
|
||||
if (data != null) {
|
||||
return JSONUtils.getObject(data, "session");
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private Map<String, Object> getActiveUser(HttpClient client) throws Exception {
|
||||
Map<String, Object> data = doPostQuery(client, GQL_TEMPLATE_ACTIVE_USER);
|
||||
if (data != null) {
|
||||
return JSONUtils.getObject(data, "user");
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private Map<String, Object> doPostQuery(HttpClient client, String gqlScript) throws Exception {
|
||||
String input = WebTestUtils.readScriptTemplate(gqlScript, CEServerTestSuite.getScriptsPath());
|
||||
List<String> headers = List.of(RPAuthProvider.X_USER, REVERSE_PROXY_TEST_USER, RPAuthProvider.X_ROLE, "user");
|
||||
Map<String, Object> map = WebTestUtils.doPostWithHeaders(CEServerTestSuite.GQL_API_URL, input, client, headers);
|
||||
return JSONUtils.getObjectOrNull(map, "data");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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: [
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"query": "\n query activeUser {\n user: activeUser {\n userId\n }\n}\n ",
|
||||
"operationName": "activeUser"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user