Account console backend should redirect to login on missing auth (#31469)
Adapted the login redirect logic from the old account console. Fixes #31469 Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
This commit is contained in:
parent
4d5c692e3e
commit
c400eff9b0
3 changed files with 72 additions and 3 deletions
|
@ -161,7 +161,7 @@ public abstract class AbstractSecuredLocalService {
|
||||||
return oauth.redirect(session.getContext().getUri(), accountUri.toString());
|
return oauth.redirect(session.getContext().getUri(), accountUri.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
static class OAuthRedirect extends AbstractOAuthClient {
|
public static class OAuthRedirect extends AbstractOAuthClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* closes client
|
* closes client
|
||||||
|
|
|
@ -2,7 +2,9 @@ package org.keycloak.services.resources.account;
|
||||||
|
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.UriBuilder;
|
||||||
import org.jboss.resteasy.reactive.NoCache;
|
import org.jboss.resteasy.reactive.NoCache;
|
||||||
import org.keycloak.authentication.requiredactions.DeleteAccount;
|
import org.keycloak.authentication.requiredactions.DeleteAccount;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
@ -17,12 +19,14 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredActionProviderModel;
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
||||||
import org.keycloak.protocol.oidc.utils.RedirectUtils;
|
import org.keycloak.protocol.oidc.utils.RedirectUtils;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.managers.AppAuthManager;
|
import org.keycloak.services.managers.AppAuthManager;
|
||||||
import org.keycloak.services.managers.Auth;
|
import org.keycloak.services.managers.Auth;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.resource.AccountResourceProvider;
|
import org.keycloak.services.resource.AccountResourceProvider;
|
||||||
|
import org.keycloak.services.resources.AbstractSecuredLocalService;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.util.ResolveRelative;
|
import org.keycloak.services.util.ResolveRelative;
|
||||||
import org.keycloak.services.util.ViteManifest;
|
import org.keycloak.services.util.ViteManifest;
|
||||||
|
@ -34,9 +38,11 @@ import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.urls.UrlType;
|
import org.keycloak.urls.UrlType;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
|
import org.keycloak.utils.StringUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -93,8 +99,13 @@ public class AccountConsole implements AccountResourceProvider {
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@NoCache
|
@NoCache
|
||||||
@Path("{any:.*}")
|
@Path("{path:.*}")
|
||||||
public Response getMainPage() throws IOException, FreeMarkerException {
|
public Response getMainPage(@PathParam("path") String path) throws IOException, FreeMarkerException {
|
||||||
|
|
||||||
|
if (auth == null) {
|
||||||
|
return redirectToLogin(path);
|
||||||
|
}
|
||||||
|
|
||||||
final var serverUriInfo = session.getContext().getUri(UrlType.FRONTEND);
|
final var serverUriInfo = session.getContext().getUri(UrlType.FRONTEND);
|
||||||
final var serverBaseUri = serverUriInfo.getBaseUri();
|
final var serverBaseUri = serverUriInfo.getBaseUri();
|
||||||
// Strip any trailing slashes from the URL.
|
// Strip any trailing slashes from the URL.
|
||||||
|
@ -195,6 +206,20 @@ public class AccountConsole implements AccountResourceProvider {
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response redirectToLogin(String path) {
|
||||||
|
UriBuilder consoleUriBuilder = Urls.accountBase(session.getContext().getUri().getBaseUri());
|
||||||
|
if (!StringUtil.isNullOrEmpty(path)) {
|
||||||
|
consoleUriBuilder.path(path);
|
||||||
|
}
|
||||||
|
URI targetUri = consoleUriBuilder.build(realm.getName());
|
||||||
|
|
||||||
|
var oauthRedirect = new AbstractSecuredLocalService.OAuthRedirect();
|
||||||
|
oauthRedirect.setAuthUrl(OIDCLoginProtocolService.authUrl(session.getContext().getUri()).build(realm.getName()).toString());
|
||||||
|
oauthRedirect.setClientId(client.getClientId());
|
||||||
|
oauthRedirect.setSecure(realm.getSslRequired().isRequired(session.getContext().getConnection()));
|
||||||
|
return oauthRedirect.redirect(session.getContext().getUri(), targetUri.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, String> supportedLocales(Properties messages) {
|
private Map<String, String> supportedLocales(Properties messages) {
|
||||||
return realm.getSupportedLocalesStream()
|
return realm.getSupportedLocalesStream()
|
||||||
.collect(Collectors.toMap(Function.identity(), l -> messages.getProperty("locale_" + l, l)));
|
.collect(Collectors.toMap(Function.identity(), l -> messages.getProperty("locale_" + l, l)));
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.keycloak.testsuite.account;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||||
|
import org.keycloak.testsuite.Assert;
|
||||||
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
|
public class AccountConsoleTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void redirectToLoginIfNotAuthenticated() throws Exception {
|
||||||
|
|
||||||
|
String accountUrl = oauth.getCurrentUri().toString().replace("/admin/master/console", "/realms/" + oauth.getRealm() + "/account");
|
||||||
|
|
||||||
|
HttpGet getAccount = new HttpGet(accountUrl);
|
||||||
|
|
||||||
|
int statusCode;
|
||||||
|
String redirectLocation;
|
||||||
|
try (var client = HttpClientBuilder.create().disableRedirectHandling().build()) {
|
||||||
|
try (var response = client.execute(getAccount)) {
|
||||||
|
statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
redirectLocation = response.getFirstHeader("Location").getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(302, statusCode);
|
||||||
|
String expectedLoginUrlPart = "/realms/" + oauth.getRealm() + "/protocol/openid-connect/auth?client_id=account";
|
||||||
|
Assert.assertTrue(redirectLocation.contains(expectedLoginUrlPart));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue