mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-05 14:30:03 -06:00
Check manage-account-links role for client initiated account linking
Closes #41914 Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
This commit is contained in:
committed by
Marek Posolda
parent
4262480bc2
commit
6dc9d0d439
@@ -1001,7 +1001,9 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||
return redirectToErrorWhenLinkingFailed(authSession, Messages.IDENTITY_PROVIDER_ALREADY_LINKED, idpDisplayName);
|
||||
}
|
||||
|
||||
if (!authenticatedUser.hasRole(this.realmModel.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.MANAGE_ACCOUNT))) {
|
||||
RoleModel manageAccountRole = this.realmModel.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.MANAGE_ACCOUNT);
|
||||
RoleModel manageAccountLinkRole = this.realmModel.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.MANAGE_ACCOUNT_LINKS);
|
||||
if (!authenticatedUser.hasRole(manageAccountRole) && !authenticatedUser.hasRole(manageAccountLinkRole)) {
|
||||
return redirectToErrorPage(authSession, Response.Status.FORBIDDEN, Messages.INSUFFICIENT_PERMISSION);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.keycloak.common.util.UriUtils;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.events.Errors;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.models.AccountRoles;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
@@ -45,6 +46,7 @@ import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.pages.IdpLinkActionPage;
|
||||
import org.keycloak.testsuite.util.AccountHelper;
|
||||
import org.keycloak.testsuite.util.oauth.OAuthClient;
|
||||
@@ -319,6 +321,84 @@ public class KcOidcBrokerIdpLinkActionTest extends AbstractInitializedBaseBroker
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccountLinkingWithDirectRoleManageAccount() throws Exception {
|
||||
// Remove "manage-account" role from user
|
||||
RealmResource consumerRealm = adminClient.realm(bc.consumerRealmName());
|
||||
String user1Id = consumerRealm.users().search("user1").iterator().next().getId();
|
||||
|
||||
RoleRepresentation defaultRoles = consumerRealm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + bc.consumerRealmName()).toRepresentation();
|
||||
consumerRealm.users().get(user1Id).roles().realmLevel().remove(Collections.singletonList(defaultRoles));
|
||||
|
||||
ClientRepresentation accountClient = ApiUtil.findClientResourceByClientId(consumerRealm, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).toRepresentation();
|
||||
RoleRepresentation manageAccount = consumerRealm.clients().get(accountClient.getId()).roles().get(AccountRoles.MANAGE_ACCOUNT).toRepresentation();
|
||||
consumerRealm.users().get(user1Id).roles().clientLevel(accountClient.getId()).add(Collections.singletonList(manageAccount));
|
||||
|
||||
loginToConsumer();
|
||||
|
||||
// Redirect to link account on behalf of "broker-app" and login to the IDP
|
||||
String kcAction = getKcActionParamForLinkIdp(bc.getIDPAlias());
|
||||
oauth.loginForm().kcAction(kcAction).open();
|
||||
confirmIdpLinking();
|
||||
|
||||
// Login to provider
|
||||
loginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
events.clear();
|
||||
grantPage.assertCurrent();
|
||||
grantPage.accept();
|
||||
|
||||
appPage.assertCurrent();
|
||||
assertKcActionParams(IdpLinkAction.PROVIDER_ID, RequiredActionContext.KcActionStatus.SUCCESS.name().toLowerCase());
|
||||
|
||||
// Check that user is linked to the IDP
|
||||
assertUserLinkedToIDP(true);
|
||||
|
||||
assertEvents((providerRealmId, providerUserId, consumerRealmId, consumerUserId, consumerUsername) -> {
|
||||
assertProviderEventsSuccess(providerRealmId, providerUserId);
|
||||
assertConsumerSuccessLinkEvents(consumerRealmId, consumerUserId, consumerUsername);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccountLinkingWithDirectRoleManageAccountLinks() throws Exception {
|
||||
// Remove "manage-account-link" role from user
|
||||
RealmResource consumerRealm = adminClient.realm(bc.consumerRealmName());
|
||||
String user1Id = consumerRealm.users().search("user1").iterator().next().getId();
|
||||
|
||||
RoleRepresentation defaultRoles = consumerRealm.roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + bc.consumerRealmName()).toRepresentation();
|
||||
consumerRealm.users().get(user1Id).roles().realmLevel().remove(Collections.singletonList(defaultRoles));
|
||||
|
||||
ClientRepresentation accountClient = ApiUtil.findClientResourceByClientId(consumerRealm, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).toRepresentation();
|
||||
RoleRepresentation manageAccountLinks = consumerRealm.clients().get(accountClient.getId()).roles().get(AccountRoles.MANAGE_ACCOUNT_LINKS).toRepresentation();
|
||||
consumerRealm.users().get(user1Id).roles().clientLevel(accountClient.getId()).add(Collections.singletonList(manageAccountLinks));
|
||||
|
||||
loginToConsumer();
|
||||
|
||||
// Redirect to link account on behalf of "broker-app" and login to the IDP
|
||||
String kcAction = getKcActionParamForLinkIdp(bc.getIDPAlias());
|
||||
oauth.loginForm().kcAction(kcAction).open();
|
||||
confirmIdpLinking();
|
||||
|
||||
// Login to provider
|
||||
loginPage.login(bc.getUserLogin(), bc.getUserPassword());
|
||||
|
||||
events.clear();
|
||||
grantPage.assertCurrent();
|
||||
grantPage.accept();
|
||||
|
||||
appPage.assertCurrent();
|
||||
assertKcActionParams(IdpLinkAction.PROVIDER_ID, RequiredActionContext.KcActionStatus.SUCCESS.name().toLowerCase());
|
||||
|
||||
// Check that user is linked to the IDP
|
||||
assertUserLinkedToIDP(true);
|
||||
|
||||
assertEvents((providerRealmId, providerUserId, consumerRealmId, consumerUserId, consumerUsername) -> {
|
||||
assertProviderEventsSuccess(providerRealmId, providerUserId);
|
||||
assertConsumerSuccessLinkEvents(consumerRealmId, consumerUserId, consumerUsername);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumerReauthentication() throws Exception {
|
||||
loginToConsumer();
|
||||
|
||||
Reference in New Issue
Block a user