This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-oauth-client.git


The following commit(s) were added to refs/heads/master by this push:
     new 3406578  SLING-12876 Principals created by OidcIdentityProvider should 
optionally have suffix of idp (#28)
3406578 is described below

commit 34065780a798d883db7eefff3d8e09f7810aa4ef
Author: Nicola Scendoni <[email protected]>
AuthorDate: Thu Oct 23 14:15:04 2025 +0200

    SLING-12876 Principals created by OidcIdentityProvider should optionally 
have suffix of idp (#28)
---
 .../impl/SlingUserInfoProcessorImpl.java           | 17 ++++++++++++---
 .../impl/SlingUserInfoProcessorImplTest.java       | 25 ++++++++++++++++++++++
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImpl.java
 
b/src/main/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImpl.java
index a8880f4..bf7ce8c 100644
--- 
a/src/main/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImpl.java
+++ 
b/src/main/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImpl.java
@@ -70,6 +70,9 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
 
         @AttributeDefinition(name = "connection", description = "OIDC 
Connection Name")
         String connection();
+
+        @AttributeDefinition(name = "idpNameInUserId", description = "Add a 
suffix with the idp in the username")
+        boolean idpNameInUserId() default false;
     }
 
     private static final Logger logger = 
LoggerFactory.getLogger(SlingUserInfoProcessorImpl.class);
@@ -80,6 +83,7 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
     private final boolean groupsInIdToken;
     private final String groupsClaimName;
     private final String connection;
+    private final boolean idpNameInUserId;
 
     @Activate
     public SlingUserInfoProcessorImpl(
@@ -93,6 +97,7 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
             throw new IllegalArgumentException("Connection name must not be 
null or empty");
         }
         this.connection = config.connection();
+        this.idpNameInUserId = config.idpNameInUserId();
     }
 
     @Override
@@ -108,7 +113,8 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
                 
Converter.toSlingOAuthTokens(tokenResponse.toSuccessResponse().getTokens());
 
         // Create AuthenticationInfo object
-        OidcAuthCredentials credentials = new OidcAuthCredentials(oidcSubject, 
idp);
+        OidcAuthCredentials credentials =
+                new OidcAuthCredentials(oidcSubject + (idpNameInUserId ? ";" + 
idp : ""), idp);
         credentials.setAttribute(".token", "");
 
         if (userInfo != null) {
@@ -138,7 +144,7 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
                         .getClaim(groupsClaimName);
                 if (groups instanceof List) {
                     logger.debug("Groups from ID Token: {}", groups);
-                    ((List) groups).forEach(group -> 
credentials.addGroup(group.toString()));
+                    ((List) groups).forEach(group -> 
credentials.addGroup(getGroupName(idp, group)));
                 }
             } catch (java.text.ParseException e) {
                 throw new RuntimeException(e);
@@ -150,7 +156,7 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
                 JSONArray groupJsonArray = (JSONArray) groups;
                 logger.debug("Groups: {}", groups);
                 // Convert the groups in a Set of Strings
-                groupJsonArray.forEach(group -> 
credentials.addGroup(group.toString()));
+                groupJsonArray.forEach(group -> 
credentials.addGroup(getGroupName(idp, group)));
             }
         }
         // Store the Access Token on user node
@@ -176,6 +182,11 @@ public class SlingUserInfoProcessorImpl implements 
UserInfoProcessor {
         return credentials;
     }
 
+    @NotNull
+    private String getGroupName(@NotNull String idp, Object group) {
+        return group.toString() + (idpNameInUserId ? ";" + idp : "");
+    }
+
     private static @Nullable UserInfo parseUserInfo(@Nullable String 
stringUserInfo) {
         if (stringUserInfo != null) {
             try {
diff --git 
a/src/test/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImplTest.java
 
b/src/test/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImplTest.java
index 3c0d867..47bea98 100644
--- 
a/src/test/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImplTest.java
+++ 
b/src/test/java/org/apache/sling/auth/oauth_client/impl/SlingUserInfoProcessorImplTest.java
@@ -153,6 +153,31 @@ class SlingUserInfoProcessorImplTest {
         assertGroupsContain(result.getGroups(), "admin", "user");
     }
 
+    @Test
+    void testProcessWithIdpInUserNameGroupsInIdToken() throws Exception {
+        // Configure to read groups from ID token
+        SlingUserInfoProcessorImpl.Config cfg = Converters.standardConverter()
+                .convert(Map.of(
+                        "groupsInIdToken", true,
+                        "storeAccessToken", false,
+                        "storeRefreshToken", false,
+                        "idpNameInUserId", true,
+                        "groupsClaimName", "groups",
+                        "connection", "test"))
+                .to(SlingUserInfoProcessorImpl.Config.class);
+        processor = new SlingUserInfoProcessorImpl(cryptoService, cfg);
+
+        // Create ID token with groups
+        List<String> groups = Arrays.asList("admin", "user");
+        String tokenResponse = 
createTokenResponseWithIdToken(TEST_ACCESS_TOKEN, TEST_REFRESH_TOKEN, groups);
+
+        OidcAuthCredentials result = processor.process(null, tokenResponse, 
TEST_SUBJECT, TEST_IDP);
+
+        assertNotNull(result);
+        assertEquals(result.getUserId(), TEST_SUBJECT + ";" + TEST_IDP);
+        assertGroupsContain(result.getGroups(), "admin" + ";" + TEST_IDP, 
"user" + ";" + TEST_IDP);
+    }
+
     @Test
     void testStoreAccessToken() throws Exception {
         when(cryptoService.encrypt(anyString())).thenReturn(ENCRYPTED_TOKEN);

Reply via email to