[KEYCLOAK-8003] - Migration to 4.2.1 extracting RESOURCE_URIs fails with fine-grained admin permissions
This commit is contained in:
parent
ee8c35a48e
commit
905fd3ae00
6 changed files with 157 additions and 19 deletions
|
@ -14,7 +14,7 @@ public class AuthzResourceUseMoreURIs extends CustomKeycloakTask {
|
||||||
@Override
|
@Override
|
||||||
protected void generateStatementsImpl() throws CustomChangeException {
|
protected void generateStatementsImpl() throws CustomChangeException {
|
||||||
try {
|
try {
|
||||||
PreparedStatement statement = jdbcConnection.prepareStatement("select ID,URI from " + getTableName("RESOURCE_SERVER_RESOURCE"));
|
PreparedStatement statement = jdbcConnection.prepareStatement("select ID,URI from " + getTableName("RESOURCE_SERVER_RESOURCE") + " where URI is not null");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ResultSet resultSet = statement.executeQuery();
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.migration;
|
package org.keycloak.testsuite.migration;
|
||||||
|
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.hamcrest.Matchers;
|
||||||
import org.keycloak.admin.client.resource.ClientResource;
|
import org.keycloak.admin.client.resource.ClientResource;
|
||||||
|
import org.keycloak.admin.client.resource.ClientsResource;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.admin.client.resource.RoleResource;
|
import org.keycloak.admin.client.resource.RoleResource;
|
||||||
import org.keycloak.common.constants.KerberosConstants;
|
import org.keycloak.common.constants.KerberosConstants;
|
||||||
|
@ -29,8 +30,6 @@ import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
|
||||||
import org.keycloak.protocol.saml.SamlProtocolFactory;
|
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||||
|
@ -43,6 +42,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
|
@ -51,7 +51,8 @@ import org.keycloak.testsuite.exportimport.ExportImportUtil;
|
||||||
import org.keycloak.testsuite.runonserver.RunHelpers;
|
import org.keycloak.testsuite.runonserver.RunHelpers;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -84,16 +85,26 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
protected RealmResource masterRealm;
|
protected RealmResource masterRealm;
|
||||||
|
|
||||||
protected void testMigratedData() {
|
protected void testMigratedData() {
|
||||||
|
testMigratedData(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testMigratedData(boolean supportsAuthzService) {
|
||||||
log.info("testing migrated data");
|
log.info("testing migrated data");
|
||||||
//master realm
|
//master realm
|
||||||
testMigratedMasterData();
|
testMigratedMasterData();
|
||||||
//migrationRealm
|
//migrationRealm
|
||||||
testMigratedMigrationData();
|
testMigratedMigrationData(supportsAuthzService);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigratedMigrationData() {
|
protected void testMigratedMigrationData(boolean supportsAuthzService) {
|
||||||
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
||||||
assertNames(migrationRealm.clients().findAll(), "account", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console");
|
List<String> expectedClientIds = new ArrayList<>(Arrays.asList("account", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console"));
|
||||||
|
|
||||||
|
if (supportsAuthzService) {
|
||||||
|
expectedClientIds.add("authz-servlet");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNames(migrationRealm.clients().findAll(), expectedClientIds.toArray(new String[expectedClientIds.size()]));
|
||||||
String id2 = migrationRealm.clients().findByClientId("migration-test-client").get(0).getId();
|
String id2 = migrationRealm.clients().findByClientId("migration-test-client").get(0).getId();
|
||||||
assertNames(migrationRealm.clients().get(id2).roles().list(), "migration-test-client-role");
|
assertNames(migrationRealm.clients().get(id2).roles().list(), "migration-test-client-role");
|
||||||
assertNames(migrationRealm.users().search("", 0, 5), "migration-test-user");
|
assertNames(migrationRealm.users().search("", 0, 5), "migration-test-user");
|
||||||
|
@ -199,8 +210,12 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
testOfflineScopeAddedToClient();
|
testOfflineScopeAddedToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo4_2_0() {
|
protected void testMigrationTo4_2_0(boolean supportsAuthzService) {
|
||||||
testRequiredActionsPriority(this.masterRealm, this.migrationRealm);
|
testRequiredActionsPriority(this.masterRealm, this.migrationRealm);
|
||||||
|
|
||||||
|
if (supportsAuthzService) {
|
||||||
|
testResourceWithMultipleUris();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testCliConsoleScopeSize(RealmResource realm) {
|
private void testCliConsoleScopeSize(RealmResource realm) {
|
||||||
|
@ -334,6 +349,13 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
assertEquals(1, migratedRulesPolicies.size());
|
assertEquals(1, migratedRulesPolicies.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void testResourceWithMultipleUris() {
|
||||||
|
ClientsResource clients = migrationRealm.clients();
|
||||||
|
ClientRepresentation clientRepresentation = clients.findByClientId("authz-servlet").get(0);
|
||||||
|
ResourceRepresentation resource = clients.get(clientRepresentation.getId()).authorization().resources().findByName("Protected Resource").get(0);
|
||||||
|
org.junit.Assert.assertThat(resource.getUris(), Matchers.containsInAnyOrder("/*"));
|
||||||
|
}
|
||||||
|
|
||||||
protected void testAuthorizationServices(RealmResource... realms) {
|
protected void testAuthorizationServices(RealmResource... realms) {
|
||||||
log.info("testing authorization services");
|
log.info("testing authorization services");
|
||||||
for (RealmResource realm : realms) {
|
for (RealmResource realm : realms) {
|
||||||
|
@ -513,8 +535,12 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
testMigrationTo3_4_2();
|
testMigrationTo3_4_2();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo4_x() {
|
protected void testMigrationTo4_x(boolean supportsAuthzServices) {
|
||||||
testMigrationTo4_0_0();
|
testMigrationTo4_0_0();
|
||||||
testMigrationTo4_2_0();
|
testMigrationTo4_2_0(supportsAuthzServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testMigrationTo4_x() {
|
||||||
|
testMigrationTo4_x(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class JsonFileImport198MigrationTest extends AbstractJsonFileImportMigrat
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void migration1_9_8Test() throws Exception {
|
public void migration1_9_8Test() throws Exception {
|
||||||
testMigratedMigrationData();
|
testMigratedMigrationData(false);
|
||||||
testMigrationTo2_0_0();
|
testMigrationTo2_0_0();
|
||||||
testMigrationTo2_1_0();
|
testMigrationTo2_1_0();
|
||||||
testMigrationTo2_2_0();
|
testMigrationTo2_2_0();
|
||||||
|
@ -71,7 +71,7 @@ public class JsonFileImport198MigrationTest extends AbstractJsonFileImportMigrat
|
||||||
testMigrationTo2_5_0();
|
testMigrationTo2_5_0();
|
||||||
//testMigrationTo2_5_1(); // Offline tokens migration is skipped for JSON
|
//testMigrationTo2_5_1(); // Offline tokens migration is skipped for JSON
|
||||||
testMigrationTo3_x();
|
testMigrationTo3_x();
|
||||||
testMigrationTo4_x();
|
testMigrationTo4_x(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -85,10 +85,10 @@ public class MigrationTest extends AbstractMigrationTest {
|
||||||
@Test
|
@Test
|
||||||
@Migration(versionFrom = "1.9.8.Final")
|
@Migration(versionFrom = "1.9.8.Final")
|
||||||
public void migration1_9_8Test() throws Exception {
|
public void migration1_9_8Test() throws Exception {
|
||||||
testMigratedData();
|
testMigratedData(false);
|
||||||
testMigrationTo2_x();
|
testMigrationTo2_x();
|
||||||
testMigrationTo3_x();
|
testMigrationTo3_x();
|
||||||
testMigrationTo4_x();
|
testMigrationTo4_x(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -96,5 +96,4 @@ public class MigrationTest extends AbstractMigrationTest {
|
||||||
public void migrationInAuthorizationServicesTest() {
|
public void migrationInAuthorizationServicesTest() {
|
||||||
testDroolsToRulesPolicyTypeMigration();
|
testDroolsToRulesPolicyTypeMigration();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2776,7 +2776,63 @@
|
||||||
"useTemplateConfig" : false,
|
"useTemplateConfig" : false,
|
||||||
"useTemplateScope" : false,
|
"useTemplateScope" : false,
|
||||||
"useTemplateMappers" : false
|
"useTemplateMappers" : false
|
||||||
} ],
|
},
|
||||||
|
{
|
||||||
|
"id": "70e8e897-82d4-49ab-82c9-c37e1a48b6bb",
|
||||||
|
"clientId": "authz-servlet",
|
||||||
|
"adminUrl": "http://localhost:8080/authz-servlet",
|
||||||
|
"baseUrl": "http://localhost:8080/authz-servlet",
|
||||||
|
"surrogateAuthRequired": false,
|
||||||
|
"enabled": true,
|
||||||
|
"clientAuthenticatorType": "client-secret",
|
||||||
|
"secret": "**********",
|
||||||
|
"redirectUris": [
|
||||||
|
"http://localhost:8080/authz-servlet/*"
|
||||||
|
],
|
||||||
|
"webOrigins": [
|
||||||
|
"http://localhost:8080"
|
||||||
|
],
|
||||||
|
"notBefore": 0,
|
||||||
|
"bearerOnly": false,
|
||||||
|
"consentRequired": false,
|
||||||
|
"standardFlowEnabled": true,
|
||||||
|
"implicitFlowEnabled": false,
|
||||||
|
"directAccessGrantsEnabled": false,
|
||||||
|
"serviceAccountsEnabled": true,
|
||||||
|
"authorizationServicesEnabled": true,
|
||||||
|
"publicClient": false,
|
||||||
|
"frontchannelLogout": false,
|
||||||
|
"protocol": "openid-connect",
|
||||||
|
"fullScopeAllowed": true,
|
||||||
|
"nodeReRegistrationTimeout": -1,
|
||||||
|
"authorizationSettings": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"name": "Admin Resource",
|
||||||
|
"uri": "/protected/admin/*",
|
||||||
|
"type": "http://servlet-authz/protected/admin",
|
||||||
|
"_id": "af06c58d-32b6-44d2-9057-2673ced120eb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Protected Resource",
|
||||||
|
"uri": "/*",
|
||||||
|
"type": "http://servlet-authz/protected/resource",
|
||||||
|
"_id": "d8ec89d2-7fc3-416c-9584-f242e8a6f827"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Premium Resource",
|
||||||
|
"uri": "/protected/premium/*",
|
||||||
|
"type": "urn:servlet-authz:protected:resource",
|
||||||
|
"_id": "9c4dd55d-b7a1-45a5-a379-d2ae48b7b309"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Main Page",
|
||||||
|
"type": "urn:servlet-authz:protected:resource",
|
||||||
|
"_id": "01394f0e-8b06-4ae8-a1cb-9f6ff7eeb6b4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}],
|
||||||
"clientTemplates" : [ ],
|
"clientTemplates" : [ ],
|
||||||
"browserSecurityHeaders" : {
|
"browserSecurityHeaders" : {
|
||||||
"xContentTypeOptions" : "nosniff",
|
"xContentTypeOptions" : "nosniff",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[ {
|
[
|
||||||
|
{
|
||||||
"id" : "Migration",
|
"id" : "Migration",
|
||||||
"realm" : "Migration",
|
"realm" : "Migration",
|
||||||
"notBefore" : 0,
|
"notBefore" : 0,
|
||||||
|
@ -983,7 +984,63 @@
|
||||||
"useTemplateConfig" : false,
|
"useTemplateConfig" : false,
|
||||||
"useTemplateScope" : false,
|
"useTemplateScope" : false,
|
||||||
"useTemplateMappers" : false
|
"useTemplateMappers" : false
|
||||||
} ],
|
},
|
||||||
|
{
|
||||||
|
"id": "70e8e897-82d4-49ab-82c9-c37e1a48b6bb",
|
||||||
|
"clientId": "authz-servlet",
|
||||||
|
"adminUrl": "http://localhost:8080/authz-servlet",
|
||||||
|
"baseUrl": "http://localhost:8080/authz-servlet",
|
||||||
|
"surrogateAuthRequired": false,
|
||||||
|
"enabled": true,
|
||||||
|
"clientAuthenticatorType": "client-secret",
|
||||||
|
"secret": "**********",
|
||||||
|
"redirectUris": [
|
||||||
|
"http://localhost:8080/authz-servlet/*"
|
||||||
|
],
|
||||||
|
"webOrigins": [
|
||||||
|
"http://localhost:8080"
|
||||||
|
],
|
||||||
|
"notBefore": 0,
|
||||||
|
"bearerOnly": false,
|
||||||
|
"consentRequired": false,
|
||||||
|
"standardFlowEnabled": true,
|
||||||
|
"implicitFlowEnabled": false,
|
||||||
|
"directAccessGrantsEnabled": false,
|
||||||
|
"serviceAccountsEnabled": true,
|
||||||
|
"authorizationServicesEnabled": true,
|
||||||
|
"publicClient": false,
|
||||||
|
"frontchannelLogout": false,
|
||||||
|
"protocol": "openid-connect",
|
||||||
|
"fullScopeAllowed": true,
|
||||||
|
"nodeReRegistrationTimeout": -1,
|
||||||
|
"authorizationSettings": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"name": "Admin Resource",
|
||||||
|
"uri": "/protected/admin/*",
|
||||||
|
"type": "http://servlet-authz/protected/admin",
|
||||||
|
"_id": "af06c58d-32b6-44d2-9057-2673ced120eb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Protected Resource",
|
||||||
|
"uri": "/*",
|
||||||
|
"type": "http://servlet-authz/protected/resource",
|
||||||
|
"_id": "d8ec89d2-7fc3-416c-9584-f242e8a6f827"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Premium Resource",
|
||||||
|
"uri": "/protected/premium/*",
|
||||||
|
"type": "urn:servlet-authz:protected:resource",
|
||||||
|
"_id": "9c4dd55d-b7a1-45a5-a379-d2ae48b7b309"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Main Page",
|
||||||
|
"type": "urn:servlet-authz:protected:resource",
|
||||||
|
"_id": "01394f0e-8b06-4ae8-a1cb-9f6ff7eeb6b4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}],
|
||||||
"clientTemplates" : [ ],
|
"clientTemplates" : [ ],
|
||||||
"browserSecurityHeaders" : {
|
"browserSecurityHeaders" : {
|
||||||
"xContentTypeOptions" : "nosniff",
|
"xContentTypeOptions" : "nosniff",
|
||||||
|
|
Loading…
Reference in a new issue