Allow admin console whoami endpoint to applications that have a special attribute
Closes #29640 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
cb3f248d73
commit
3304540855
4 changed files with 39 additions and 4 deletions
|
@ -22,7 +22,9 @@
|
||||||
"publicClient": true,
|
"publicClient": true,
|
||||||
"frontchannelLogout": false,
|
"frontchannelLogout": false,
|
||||||
"protocol": "openid-connect",
|
"protocol": "openid-connect",
|
||||||
"attributes": {},
|
"attributes": {
|
||||||
|
"security.admin.console": "true"
|
||||||
|
},
|
||||||
"authenticationFlowBindingOverrides": {},
|
"authenticationFlowBindingOverrides": {},
|
||||||
"fullScopeAllowed": true,
|
"fullScopeAllowed": true,
|
||||||
"nodeReRegistrationTimeout": -1,
|
"nodeReRegistrationTimeout": -1,
|
||||||
|
@ -44,4 +46,4 @@
|
||||||
"configure": true,
|
"configure": true,
|
||||||
"manage": true
|
"manage": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,4 +171,7 @@ public final class Constants {
|
||||||
|
|
||||||
// Sent to clients when authentication session expired, but user is already logged-in in current browser
|
// Sent to clients when authentication session expired, but user is already logged-in in current browser
|
||||||
public static final String AUTHENTICATION_EXPIRED_MESSAGE = "authentication_expired";
|
public static final String AUTHENTICATION_EXPIRED_MESSAGE = "authentication_expired";
|
||||||
|
|
||||||
|
// attribute name used in apps to mark that it is an admin console and its azp is allowed
|
||||||
|
public static final String SECURITY_ADMIN_CONSOLE_ATTR = "security.admin.console";
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,8 +216,16 @@ public class AdminConsole {
|
||||||
throw new NotAuthorizedException("Bearer");
|
throw new NotAuthorizedException("Bearer");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Constants.ADMIN_CONSOLE_CLIENT_ID.equals(authResult.getToken().getIssuedFor())) {
|
final String issuedFor = authResult.getToken().getIssuedFor();
|
||||||
throw new ForbiddenException("Token not valid for admin console");
|
if (!Constants.ADMIN_CONSOLE_CLIENT_ID.equals(issuedFor)) {
|
||||||
|
if (issuedFor == null) {
|
||||||
|
throw new ForbiddenException("No azp claim in the token");
|
||||||
|
}
|
||||||
|
// check the attribute to see if the app is defined as an admin console
|
||||||
|
ClientModel client = session.clients().getClientByClientId(realm, issuedFor);
|
||||||
|
if (client == null || !Boolean.parseBoolean(client.getAttribute(Constants.SECURITY_ADMIN_CONSOLE_ATTR))) {
|
||||||
|
throw new ForbiddenException("Token issued for an application that is not the admin console: " + issuedFor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel user= authResult.getUser();
|
UserModel user= authResult.getUser();
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||||
import org.keycloak.testsuite.broker.util.SimpleHttpDefault;
|
import org.keycloak.testsuite.broker.util.SimpleHttpDefault;
|
||||||
import org.keycloak.testsuite.console.page.AdminConsole;
|
import org.keycloak.testsuite.console.page.AdminConsole;
|
||||||
|
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||||
import org.keycloak.testsuite.util.AdminClientUtil;
|
import org.keycloak.testsuite.util.AdminClientUtil;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.RealmBuilder;
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
|
@ -289,4 +290,25 @@ public class AdminConsoleWhoAmILocaleTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLocaleRealmTokenForOtherClientButAllowed() throws Exception {
|
||||||
|
try (ClientAttributeUpdater updater = ClientAttributeUpdater.forClient(adminClient, REALM_I18N_ON, Constants.ADMIN_CLI_CLIENT_ID)
|
||||||
|
.setAttribute(Constants.SECURITY_ADMIN_CONSOLE_ATTR, Boolean.TRUE.toString())
|
||||||
|
.update();
|
||||||
|
Keycloak adminCliClient = AdminClientUtil.createAdminClient(true, REALM_I18N_ON,
|
||||||
|
USER_WITH_LOCALE, PASSWORD, Constants.ADMIN_CLI_CLIENT_ID, null)) {
|
||||||
|
AccessTokenResponse accessToken = adminCliClient.tokenManager().getAccessToken();
|
||||||
|
Assert.assertNotNull(accessToken);
|
||||||
|
String token = accessToken.getToken();
|
||||||
|
JsonNode whoAmI = SimpleHttpDefault
|
||||||
|
.doGet(whoAmiUrl(REALM_I18N_ON), client)
|
||||||
|
.header("Accept", "application/json")
|
||||||
|
.auth(token)
|
||||||
|
.asJson();
|
||||||
|
Assert.assertEquals(REALM_I18N_ON, whoAmI.get("realm").asText());
|
||||||
|
Assert.assertEquals(USER_LOCALE, whoAmI.get("locale").asText());
|
||||||
|
checkRealmAccess(REALM_I18N_ON, whoAmI);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue