diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java index 2e7e035d03..22ff391301 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java @@ -24,6 +24,7 @@ import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.jboss.resteasy.reactive.NoCache; import jakarta.ws.rs.NotFoundException; +import org.keycloak.common.util.Encode; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.models.ClientModel; @@ -202,7 +203,7 @@ public class RoleContainerResource extends RoleResource { adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getName()).representation(rep).success(); - return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build(); + return Response.created(uriInfo.getAbsolutePathBuilder().path(Encode.encodePathSegmentAsIs(role.getName())).build()).build(); } catch (ModelDuplicateException e) { throw ErrorResponse.exists("Role with name " + rep.getName() + " already exists"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java index 07f60ac0d3..618e8fffa5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/ClientRolesTest.java @@ -110,6 +110,12 @@ public class ClientRolesTest extends AbstractClientTest { rolesRsc.create(role); } + @Test + public void createRoleWithNamePattern() { + RoleRepresentation role = RoleBuilder.create().name("role-a-{pattern}").build(); + rolesRsc.create(role); + } + @Test public void testRemoveRole() { RoleRepresentation role2 = makeRole("role2");