dbeaver/cloudbeaver#4417 add redirect on the same tab (#4502)

* dbeaver/cloudbeaver#4417 add redirect on the same tab

* dbeaver/pro#4417 feat:support full-page redirect

* dbeaver/pro#4417 refactor: remove extra type

* dbeaver/pro#4417 feat: skip navigation when in-tab redirect

* Revert "dbeaver/pro#4417 feat: skip navigation when in-tab redirect"

This reverts commit 4244d41582.

---------

Co-authored-by: Sychev Andrey <44414066+SychevAndrey@users.noreply.github.com>
Co-authored-by: Sychev Andrey <nukemoore@gmail.com>
Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
Ruslan Musaev
2026-08-05 16:46:01 +02:00
committed by GitHub
co-authored by Sychev Andrey Sychev Andrey Evgenia
parent 1b8ea64cd0
commit eed9cd979e
10 changed files with 69 additions and 11 deletions
@@ -59,6 +59,7 @@ public class WebAuthProviderDescriptor extends AbstractDescriptor {
private final boolean isPrivate;
private final boolean isAuthHidden;
private final boolean isCaseInsensitive;
private final boolean sameTabRedirectOnLogout;
private final boolean serviceProvider;
private final String[] requiredFeatures;
private final boolean isRequired;
@@ -75,6 +76,7 @@ public class WebAuthProviderDescriptor extends AbstractDescriptor {
this.isRequired = CommonUtils.toBoolean(cfg.getAttribute(WebRegistryConstant.ATTR_REQUIRED));
this.isAuthHidden = CommonUtils.toBoolean(cfg.getAttribute(WebRegistryConstant.ATTR_AUTH_HIDDEN));
this.isCaseInsensitive = CommonUtils.toBoolean(cfg.getAttribute(WebRegistryConstant.ATTR_CASE_INSENSITIVE));
this.sameTabRedirectOnLogout = CommonUtils.toBoolean(cfg.getAttribute(WebRegistryConstant.ATTR_SAME_TAB_LOGOUT_REDIRECT));
this.serviceProvider = CommonUtils.toBoolean(cfg.getAttribute(WebRegistryConstant.ATTR_SERVICE_PROVIDER));
for (IConfigurationElement cfgElement : cfg.getChildren(WebRegistryConstant.TAG_CONFIGURATION)) {
@@ -129,6 +131,10 @@ public class WebAuthProviderDescriptor extends AbstractDescriptor {
return trusted;
}
public boolean isSameTabRedirectOnLogout() {
return sameTabRedirectOnLogout;
}
public boolean isPrivate() {
return isPrivate;
}
@@ -29,6 +29,7 @@ public class WebRegistryConstant {
public static final String ATTR_REQUIRED = "required";
public static final String ATTR_AUTH_HIDDEN = "authHidden";
public static final String ATTR_CASE_INSENSITIVE = "caseInsensitive";
public static final String ATTR_SAME_TAB_LOGOUT_REDIRECT = "sameTabRedirectOnLogout";
public static final String ATTR_REQUIRED_FEATURES = "requiredFeatures";
public static final String ATTR_CATEGORIES = "categories";
public static final String ATTR_SERVICE_PROVIDER = "serviceProvider";
@@ -108,8 +108,14 @@ type FederatedAuthResult @since(version: "25.0.3") {
userTokens: [UserAuthToken!]! @since(version: "25.0.3")
}
type LogoutLink @since(version: "26.1.4") {
url: String!
"If true, the URL must be opened as a full-page redirect in the current tab instead of a popup window"
sameTabRedirect: Boolean!
}
type LogoutInfo @since(version: "23.3.3") {
redirectLinks: [String!]!
redirectLinks: [LogoutLink!]!
}
type UserAuthToken {
@@ -20,5 +20,5 @@ import org.jkiss.code.NotNull;
import java.util.List;
public record WebLogoutInfo(@NotNull List<String> redirectLinks) {
public record WebLogoutInfo(@NotNull List<WebLogoutLink> redirectLinks) {
}
@@ -0,0 +1,29 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.cloudbeaver.service.auth;
import org.jkiss.code.NotNull;
/**
* A single logout redirect link.
*
* @param url the URL to open on logout
* @param sameTabRedirect if true, the URL must be opened as a full-page redirect
* in the current tab instead of a popup window
*/
public record WebLogoutLink(@NotNull String url, boolean sameTabRedirect) {
}
@@ -249,7 +249,7 @@ public class WebServiceAuthImpl implements DBWServiceAuth {
List<WebAuthInfo> removedInfos = webSession.removeAuthInfo(providerId);
var cbApp = CBApplication.getInstance();
List<String> logoutUrls = new ArrayList<>();
List<WebLogoutLink> redirectLinks = new ArrayList<>();
String origin = ServletAppUtils.getOriginFromRequest(httpRequest);
for (WebAuthInfo removedInfo : removedInfos) {
if (removedInfo.getAuthProviderDescriptor()
@@ -274,11 +274,14 @@ public class WebServiceAuthImpl implements DBWServiceAuth {
);
}
if (CommonUtils.isNotEmpty(logoutUrl)) {
logoutUrls.add(logoutUrl);
redirectLinks.add(new WebLogoutLink(
logoutUrl,
removedInfo.getAuthProviderDescriptor().isSameTabRedirectOnLogout()
));
}
}
}
return new WebLogoutInfo(logoutUrls);
return new WebLogoutInfo(redirectLinks);
} catch (DBException e) {
throw new DBWebException("User logout failed", e);
}
@@ -20,6 +20,7 @@
description="Reverse proxy header based authentication"
trusted="true"
configurable="true"
sameTabRedirectOnLogout="true"
class="io.cloudbeaver.auth.provider.rp.RPAuthProvider"
icon="platform:/plugin/org.jkiss.dbeaver.model/icons/tree/key.svg">
<credentials>
@@ -1,6 +1,6 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 DBeaver Corp and others
* Copyright (C) 2010-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,10 @@ public class AuthenticationTest extends CloudbeaverMockTest {
private static final String GQL_AUTH_LOGOUT = """
query authLogoutExtended($provider: ID, $configuration: ID) {
result: authLogoutExtended(provider: $provider, configuration: $configuration) {
redirectLinks
redirectLinks {
url
sameTabRedirect
}
}
}""";
@@ -1,5 +1,8 @@
query authLogout($provider: ID, $configuration: ID) {
result: authLogoutExtended(provider: $provider, configuration: $configuration) {
redirectLinks
redirectLinks {
url
sameTabRedirect
}
}
}
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -125,11 +125,17 @@ export class AuthenticationService extends Bootstrap {
const redirectLinks = userLogoutInfo.redirectLinks;
if (redirectLinks.length) {
const url = redirectLinks[0];
const redirectLink = redirectLinks[0]!;
if (redirectLink.sameTabRedirect) {
window.location.replace(redirectLink.url);
return;
}
const id = `okta-logout-id-${uuid()}`;
const popup = this.windowsService.open(id, {
url,
url: redirectLink.url,
target: id,
width: 600,
height: 700,