Escape $ sign when replacing clientId in the role mappers
Closes https://github.com/keycloak/keycloak/issues/23692
This commit is contained in:
parent
70e820469a
commit
d7bb59461d
2 changed files with 8 additions and 11 deletions
|
@ -75,10 +75,7 @@ abstract class AbstractUserRoleMappingMapper extends AbstractOIDCProtocolMapper
|
|||
}
|
||||
|
||||
|
||||
private static final Pattern CLIENT_ID_PATTERN = Pattern.compile("\\$\\{client_id\\}");
|
||||
|
||||
private static final Pattern DOT_PATTERN = Pattern.compile("\\.");
|
||||
private static final String DOT_REPLACEMENT = "\\\\\\\\.";
|
||||
private static final Pattern CLIENT_ID_PATTERN = Pattern.compile(Pattern.quote("${client_id}"));
|
||||
|
||||
private static void mapClaim(IDToken token, ProtocolMapperModel mappingModel, Object attributeValue, String clientId) {
|
||||
attributeValue = OIDCAttributeMapperHelper.mapAttributeValue(mappingModel, attributeValue);
|
||||
|
@ -90,11 +87,10 @@ abstract class AbstractUserRoleMappingMapper extends AbstractOIDCProtocolMapper
|
|||
}
|
||||
|
||||
if (clientId != null) {
|
||||
// case when clientId contains dots
|
||||
clientId = DOT_PATTERN.matcher(clientId).replaceAll(DOT_REPLACEMENT);
|
||||
Matcher matcher = CLIENT_ID_PATTERN.matcher(protocolClaim);
|
||||
if (matcher.find()) {
|
||||
protocolClaim = matcher.replaceAll(clientId);
|
||||
// dots and backslashes in clientId should be escaped first for the claim
|
||||
protocolClaim = matcher.replaceAll(Matcher.quoteReplacement(clientId.replace("\\", "\\\\").replace(".", "\\.")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -235,8 +235,9 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
|||
@Test
|
||||
public void testSuccess_dotsInClientId() throws Exception {
|
||||
// Create client with dot in the name
|
||||
final String clientId = "my.foo.$\\client\\$";
|
||||
ClientRepresentation clientRep = org.keycloak.testsuite.util.ClientBuilder.create()
|
||||
.clientId("my.foo.client")
|
||||
.clientId(clientId)
|
||||
.addRedirectUri("http://foo.host")
|
||||
.secret("password")
|
||||
.directAccessGrants()
|
||||
|
@ -258,11 +259,11 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
|||
userResource.roles().clientLevel(clientUUID).add(Collections.singletonList(fooRole));
|
||||
|
||||
// Login to the new client
|
||||
OAuthClient.AccessTokenResponse accessTokenResponse = oauth.clientId("my.foo.client")
|
||||
OAuthClient.AccessTokenResponse accessTokenResponse = oauth.clientId(clientId)
|
||||
.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
|
||||
|
||||
AccessToken accessToken = oauth.verifyToken(accessTokenResponse.getAccessToken());
|
||||
Assert.assertNames(accessToken.getResourceAccess("my.foo.client").getRoles(), "my.foo.role");
|
||||
Assert.assertNames(accessToken.getResourceAccess(clientId).getRoles(), "my.foo.role");
|
||||
|
||||
events.clear();
|
||||
|
||||
|
@ -271,7 +272,7 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
|||
try {
|
||||
Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getAccessToken());
|
||||
|
||||
testSuccessfulUserInfoResponse(response, "my.foo.client");
|
||||
testSuccessfulUserInfoResponse(response, clientId);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue