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

tiagobento pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git


The following commit(s) were added to refs/heads/main by this push:
     new 0b99949587 [incubator-kie-issues-1597] Enforce authentication in User 
Tasks rest endpoints (#3758)
0b99949587 is described below

commit 0b999495874a1db93800ac529f5994c4a7ff9c5f
Author: Pere Fernández <[email protected]>
AuthorDate: Fri Nov 1 14:46:50 2024 +0100

    [incubator-kie-issues-1597] Enforce authentication in User Tasks rest 
endpoints (#3758)
    
    * [incubator-kie-issues-1597] Enforce authentication in User Tasks rest 
endpoints
    
    * Added configs
    
    * - formatting
    
    * - fix config
---
 .../java/org/kie/kogito/auth/IdentityProvider.java |  2 +-
 ...yProvider.java => IdentityProviderFactory.java} | 26 +++-----
 .../auth/impl/IdentityProviderFactoryImpl.java     | 52 ++++++++++++++++
 .../KogitoAuthConfig.java}                         | 41 +++++--------
 .../auth/impl/IdentityProviderFactoryImplTest.java | 70 ++++++++++++++++++++++
 .../RestResourceQuarkusTemplate.java               | 14 ++---
 .../RestResourceSpringTemplate.java                | 15 ++---
 .../RestResourceWorkItemQuarkusTemplate.java       | 15 +++--
 .../RestResourceWorkItemSpringTemplate.java        | 15 +++--
 .../RestResourceUserTaskQuarkusTemplate.java       | 44 +++++++-------
 .../RestResourceUserTaskSpringTemplate.java        | 37 ++++++------
 .../QuarkusIdentityProviderFactoryProducer.java    | 56 +++++++++++++++++
 ...imeConfig.java => KogitoAuthRuntimeConfig.java} | 27 ++++-----
 .../kogito/quarkus/config/KogitoRuntimeConfig.java |  6 ++
 .../SpringIdentityProviderFactoryProducer.java     | 43 +++++++++++++
 15 files changed, 326 insertions(+), 137 deletions(-)

diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
index 1bbbdc6719..5a837667ac 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
@@ -27,7 +27,7 @@ import java.util.Collection;
 public interface IdentityProvider {
 
     /**
-     * Returns name assigned to the current context, usually refers to user 
name
+     * Returns name assigned to the current context, usually refers to the 
username
      * 
      * @return assigned name taken from security context
      */
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProviderFactory.java
similarity index 57%
copy from api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
copy to 
api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProviderFactory.java
index 1bbbdc6719..0d44e9274a 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
+++ 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProviderFactory.java
@@ -16,35 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.kie.kogito.auth;
 
 import java.util.Collection;
 
 /**
- * Delivers security information about given identity that includes name and 
assigned roles.
- *
+ * Factory that resolves the {@link IdentityProvider}
  */
-public interface IdentityProvider {
+public interface IdentityProviderFactory {
 
     /**
-     * Returns name assigned to the current context, usually refers to user 
name
-     * 
-     * @return assigned name taken from security context
+     * Enables (true) using the application security context when resolving 
current User Identity. Defaults to false.
      */
-    String getName();
+    String KOGITO_SECURITY_AUTH_ENABLED = "kogito.security.auth.enabled";
 
     /**
-     * Returns roles assigned to the current context if any
-     * 
-     * @return Collection of assigned roles or empty one
+     * Comma-separated list of roles that allow identity impersonation when 
resolving the actual User Identity.
      */
-    Collection<String> getRoles();
+    String KOGITO_SECURITY_AUTH_IMPERSONATION_ALLOWED_FOR_ROLES = 
"kogito.security.auth.impersonation.allowed-for-roles";
 
-    /**
-     * Checks if given role is assigned to current context
-     * 
-     * @param role role to be checked
-     * @return true if the role is found otherwise null
-     */
-    boolean hasRole(String role);
+    IdentityProvider getOrImpersonateIdentity(String user, Collection<String> 
roles);
 }
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/auth/impl/IdentityProviderFactoryImpl.java
 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/impl/IdentityProviderFactoryImpl.java
new file mode 100644
index 0000000000..655ed5daa3
--- /dev/null
+++ 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/impl/IdentityProviderFactoryImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.kie.kogito.auth.impl;
+
+import java.util.Collection;
+
+import org.kie.kogito.auth.IdentityProvider;
+import org.kie.kogito.auth.IdentityProviderFactory;
+import org.kie.kogito.auth.IdentityProviders;
+
+public class IdentityProviderFactoryImpl implements IdentityProviderFactory {
+
+    private final IdentityProvider identityProvider;
+    private final KogitoAuthConfig config;
+
+    public IdentityProviderFactoryImpl(IdentityProvider identityProvider, 
KogitoAuthConfig config) {
+        this.identityProvider = identityProvider;
+        this.config = config;
+    }
+
+    @Override
+    public IdentityProvider getOrImpersonateIdentity(String user, 
Collection<String> roles) {
+
+        if (!config.isEnabled()) {
+            return IdentityProviders.of(user, roles);
+        }
+
+        Collection<String> identityRoles = identityProvider.getRoles();
+        if 
(config.getRolesThatAllowImpersonation().stream().anyMatch(identityRoles::contains))
 {
+            return IdentityProviders.of(user, roles);
+        }
+
+        return identityProvider;
+    }
+}
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/impl/KogitoAuthConfig.java
similarity index 53%
copy from api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
copy to 
api/kogito-api/src/main/java/org/kie/kogito/auth/impl/KogitoAuthConfig.java
index 1bbbdc6719..c66687fd02 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/auth/IdentityProvider.java
+++ 
b/api/kogito-api/src/main/java/org/kie/kogito/auth/impl/KogitoAuthConfig.java
@@ -16,35 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.auth;
+
+package org.kie.kogito.auth.impl;
 
 import java.util.Collection;
 
-/**
- * Delivers security information about given identity that includes name and 
assigned roles.
- *
- */
-public interface IdentityProvider {
+public class KogitoAuthConfig {
+
+    private final boolean enabled;
+    private final Collection<String> rolesThatAllowImpersonation;
 
-    /**
-     * Returns name assigned to the current context, usually refers to user 
name
-     * 
-     * @return assigned name taken from security context
-     */
-    String getName();
+    public KogitoAuthConfig(boolean enabled, Collection<String> 
rolesThatAllowImpersonation) {
+        this.enabled = enabled;
+        this.rolesThatAllowImpersonation = rolesThatAllowImpersonation;
+    }
 
-    /**
-     * Returns roles assigned to the current context if any
-     * 
-     * @return Collection of assigned roles or empty one
-     */
-    Collection<String> getRoles();
+    public boolean isEnabled() {
+        return enabled;
+    }
 
-    /**
-     * Checks if given role is assigned to current context
-     * 
-     * @param role role to be checked
-     * @return true if the role is found otherwise null
-     */
-    boolean hasRole(String role);
+    public Collection<String> getRolesThatAllowImpersonation() {
+        return rolesThatAllowImpersonation;
+    }
 }
diff --git 
a/api/kogito-api/src/test/java/org/kie/kogito/auth/impl/IdentityProviderFactoryImplTest.java
 
b/api/kogito-api/src/test/java/org/kie/kogito/auth/impl/IdentityProviderFactoryImplTest.java
new file mode 100644
index 0000000000..967d85a478
--- /dev/null
+++ 
b/api/kogito-api/src/test/java/org/kie/kogito/auth/impl/IdentityProviderFactoryImplTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.kie.kogito.auth.impl;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.kie.kogito.auth.IdentityProviders;
+
+public class IdentityProviderFactoryImplTest {
+
+    private static final String KOGITO_IDENTITY_USER = "john";
+    private static final Collection<String> KOGITO_IDENTITY_ROLES = 
List.of("IT", "task-operator");
+    private static final Collection<String> KOGITO_IDENTITY_IMPERSONATOR_ROLES 
= List.of("root", "task-admin");
+    private static final String TEST_USER = "katty";
+    private static final Collection<String> TEST_ROLES = List.of("HR", 
"task-operator");
+
+    @Test
+    public void testResolveIdentityWithAuthDisabled() {
+        KogitoAuthConfig config = new KogitoAuthConfig(false, 
KOGITO_IDENTITY_IMPERSONATOR_ROLES);
+        IdentityProviderFactoryImpl identityProviderFactory = new 
IdentityProviderFactoryImpl(IdentityProviders.of(KOGITO_IDENTITY_USER, 
KOGITO_IDENTITY_ROLES), config);
+
+        
Assertions.assertThat(identityProviderFactory.getOrImpersonateIdentity(TEST_USER,
 TEST_ROLES))
+                .isNotNull()
+                .hasFieldOrPropertyWithValue("name", TEST_USER)
+                .matches(identityProvider -> 
identityProvider.getRoles().containsAll(TEST_ROLES));
+    }
+
+    @Test
+    public void testResolveIdentityWithAuthEnabled() {
+        KogitoAuthConfig config = new KogitoAuthConfig(true, 
KOGITO_IDENTITY_IMPERSONATOR_ROLES);
+        IdentityProviderFactoryImpl identityProviderFactory = new 
IdentityProviderFactoryImpl(IdentityProviders.of(KOGITO_IDENTITY_USER, 
KOGITO_IDENTITY_ROLES), config);
+
+        
Assertions.assertThat(identityProviderFactory.getOrImpersonateIdentity(TEST_USER,
 TEST_ROLES))
+                .isNotNull()
+                .hasFieldOrPropertyWithValue("name", KOGITO_IDENTITY_USER)
+                .matches(identityProvider -> 
identityProvider.getRoles().containsAll(KOGITO_IDENTITY_ROLES));
+    }
+
+    @Test
+    public void testResolveImpersonatedIdentityWithAuthEnabled() {
+        KogitoAuthConfig config = new KogitoAuthConfig(true, 
KOGITO_IDENTITY_IMPERSONATOR_ROLES);
+        IdentityProviderFactoryImpl identityProviderFactory = new 
IdentityProviderFactoryImpl(IdentityProviders.of(KOGITO_IDENTITY_USER, 
KOGITO_IDENTITY_IMPERSONATOR_ROLES), config);
+
+        
Assertions.assertThat(identityProviderFactory.getOrImpersonateIdentity(TEST_USER,
 TEST_ROLES))
+                .isNotNull()
+                .hasFieldOrPropertyWithValue("name", TEST_USER)
+                .matches(identityProvider -> 
identityProvider.getRoles().containsAll(TEST_ROLES));
+    }
+
+}
diff --git 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java
 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java
index 0bbf0b10a6..130628cd57 100644
--- 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java
+++ 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java
@@ -18,7 +18,6 @@
  */
 package com.myspace.demo;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -50,17 +49,11 @@ import 
org.eclipse.microprofile.openapi.annotations.tags.Tag;
 import org.jbpm.util.JsonSchemaUtil;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
-import org.kie.kogito.process.WorkItem;
 import org.kie.kogito.process.ProcessService;
 import org.kie.kogito.process.workitem.TaskModel;
-import org.kie.kogito.auth.IdentityProvider;
-import org.kie.kogito.auth.IdentityProviders;
+import org.kie.kogito.auth.IdentityProviderFactory;
 import org.kie.kogito.auth.SecurityPolicy;
 
-import org.kie.kogito.usertask.model.Attachment;
-import org.kie.kogito.usertask.model.AttachmentInfo;
-import org.kie.kogito.usertask.model.Comment;
-
 @Path("/$name$")
 public class $Type$Resource {
 
@@ -69,6 +62,9 @@ public class $Type$Resource {
     @Inject
     ProcessService processService;
 
+    @Inject
+    IdentityProviderFactory identityProviderFactory;
+
     @POST
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
@@ -144,7 +140,7 @@ public class $Type$Resource {
     public List<TaskModel> getTasks_$name$(@PathParam("id") String id,
                                           @QueryParam("user") final String 
user,
                                           @QueryParam("group") final 
List<String> groups) {
-        return processService.getWorkItems(process, id, 
SecurityPolicy.of(IdentityProviders.of(user, groups)))
+        return processService.getWorkItems(process, id, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)))
                 .orElseThrow(NotFoundException::new)
                 .stream()
                 .map($TaskModelFactory$::from)
diff --git 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java
 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java
index 190a38af3b..0c5cb82f6f 100644
--- 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java
+++ 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java
@@ -18,8 +18,6 @@
  */
 package com.myspace.demo;
 
-import java.net.URI;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -28,17 +26,11 @@ import java.util.stream.Collectors;
 import org.jbpm.util.JsonSchemaUtil;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
-import org.kie.kogito.process.WorkItem;
 import org.kie.kogito.process.ProcessService;
 import org.kie.kogito.process.workitem.TaskModel;
-import org.kie.kogito.auth.IdentityProvider;
-import org.kie.kogito.auth.IdentityProviders;
+import org.kie.kogito.auth.IdentityProviderFactory;
 import org.kie.kogito.auth.SecurityPolicy;
 
-import org.kie.kogito.usertask.model.Attachment;
-import org.kie.kogito.usertask.model.AttachmentInfo;
-import org.kie.kogito.usertask.model.Comment;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
@@ -70,6 +62,9 @@ public class $Type$Resource {
     @Autowired
     ProcessService processService;
 
+    @Autowired
+    IdentityProviderFactory identityProviderFactory;
+
     @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE, consumes = 
MediaType.APPLICATION_JSON_VALUE)
     @Operation(summary = "$documentation$", description = 
"$processInstanceDescription$")
     public ResponseEntity<$Type$Output> createResource_$name$(@RequestHeader 
HttpHeaders httpHeaders,
@@ -128,7 +123,7 @@ public class $Type$Resource {
     public List<TaskModel> getTasks_$name$(@PathVariable("id") String id,
                                            @RequestParam(value = "user", 
required = false) final String user,
                                            @RequestParam(value = "group", 
required = false) final List<String> groups) {
-        return processService.getWorkItems(process, id, 
SecurityPolicy.of(IdentityProviders.of(user, groups)))
+        return processService.getWorkItems(process, id, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)))
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND))
                 .stream()
                 .map($TaskModelFactory$::from)
diff --git 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemQuarkusTemplate.java
 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemQuarkusTemplate.java
index 2bf6dd3bc6..cff68fad0f 100644
--- 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemQuarkusTemplate.java
+++ 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemQuarkusTemplate.java
@@ -25,7 +25,6 @@ import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.UriInfo;
 
-import org.kie.kogito.auth.IdentityProviders;
 import org.kie.kogito.auth.SecurityPolicy;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
@@ -47,7 +46,7 @@ public class $Type$Resource {
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups,
             @Context UriInfo uriInfo) {
-        return processService.signalWorkItem(process, id, "$taskName$", 
SecurityPolicy.of(user, groups))
+        return processService.signalWorkItem(process, id, "$taskName$", 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)))
                 .map(task -> Response
                         
.created(uriInfo.getAbsolutePathBuilder().path(task.getId()).build())
                         .entity(task.getResults())
@@ -65,7 +64,7 @@ public class $Type$Resource {
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups,
             final $TaskOutput$ model) {
-        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(user, groups), model)
+        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), model)
                 .orElseThrow(NotFoundException::new);
     }
 
@@ -77,7 +76,7 @@ public class $Type$Resource {
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups,
             final $TaskOutput$ model) {
-        return processService.setWorkItemOutput(process, id, taskId, 
SecurityPolicy.of(user, groups), model, $TaskOutput$::fromMap)
+        return processService.setWorkItemOutput(process, id, taskId, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), model, $TaskOutput$::fromMap)
                 .orElseThrow(NotFoundException::new);
     }
 
@@ -92,7 +91,7 @@ public class $Type$Resource {
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups,
             final $TaskOutput$ model) {
-        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(user, groups), model)
+        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), model)
                 .orElseThrow(NotFoundException::new);
     }
 
@@ -103,7 +102,7 @@ public class $Type$Resource {
             @PathParam("taskId") String taskId,
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups) {
-        return processService.getWorkItem(process, id, taskId, 
SecurityPolicy.of(user, groups), $TaskModel$::from)
+        return processService.getWorkItem(process, id, taskId, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), $TaskModel$::from)
                 .orElseThrow(NotFoundException::new);
     }
 
@@ -115,7 +114,7 @@ public class $Type$Resource {
             @QueryParam("phase") @DefaultValue("abort") final String phase,
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups) {
-        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(user, groups), null)
+        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), null)
                 .orElseThrow(NotFoundException::new);
     }
 
@@ -133,7 +132,7 @@ public class $Type$Resource {
             @PathParam("taskId") final String taskId,
             @QueryParam("user") final String user,
             @QueryParam("group") final List<String> groups) {
-        return processService.getWorkItemSchemaAndPhases(process, id, taskId, 
"$taskName$", SecurityPolicy.of(user, groups));
+        return processService.getWorkItemSchemaAndPhases(process, id, taskId, 
"$taskName$", 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)));
     }
 
 }
diff --git 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemSpringTemplate.java
 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemSpringTemplate.java
index 7a5e65aea2..88659fb800 100644
--- 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemSpringTemplate.java
+++ 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceWorkItemSpringTemplate.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.jbpm.util.JsonSchemaUtil;
-import org.kie.kogito.auth.IdentityProviders;
 import org.kie.kogito.auth.SecurityPolicy;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.WorkItem;
@@ -52,7 +51,7 @@ public class $Type$Resource {
             @RequestParam("group") final List<String> groups,
             final UriComponentsBuilder uriComponentsBuilder) {
 
-        return processService.signalWorkItem(process, id, "$taskName$", 
SecurityPolicy.of(user, groups))
+        return processService.signalWorkItem(process, id, "$taskName$", 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)))
                 .map(task -> ResponseEntity
                         .created(uriComponentsBuilder
                                 .path("/$name$/{id}/$taskName$/{taskId}")
@@ -69,7 +68,7 @@ public class $Type$Resource {
             @RequestParam("user") final String user,
             @RequestParam("group") final List<String> groups,
             @RequestBody(required = false) final $TaskOutput$ model) {
-        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(user, groups), model)
+        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), model)
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -79,7 +78,7 @@ public class $Type$Resource {
             @RequestParam(value = "user", required = false) final String user,
             @RequestParam(value = "group", required = false) final 
List<String> groups,
             @RequestBody(required = false) final $TaskOutput$ model) {
-        return processService.setWorkItemOutput(process, id, taskId, 
SecurityPolicy.of(user, groups), model, $TaskOutput$::fromMap)
+        return processService.setWorkItemOutput(process, id, taskId, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), model, $TaskOutput$::fromMap)
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -94,7 +93,7 @@ public class $Type$Resource {
             @RequestParam(value = "group",
                     required = false) final List<String> groups,
             @RequestBody(required = false) final $TaskOutput$ model) {
-        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(user, groups), model)
+        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), model)
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -104,7 +103,7 @@ public class $Type$Resource {
             @RequestParam(value = "user", required = false) final String user,
             @RequestParam(value = "group",
                     required = false) final List<String> groups) {
-        return processService.getWorkItem(process, id, taskId, 
SecurityPolicy.of(user, groups), $TaskModel$::from)
+        return processService.getWorkItem(process, id, taskId, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), $TaskModel$::from)
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -116,7 +115,7 @@ public class $Type$Resource {
             @RequestParam(value = "user", required = false) final String user,
             @RequestParam(value = "group",
                     required = false) final List<String> groups) {
-        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(user, groups), null)
+        return processService.transitionWorkItem(process, id, taskId, phase, 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)), null)
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -131,7 +130,7 @@ public class $Type$Resource {
             @RequestParam(value = "user", required = false) final String user,
             @RequestParam(value = "group",
                     required = false) final List<String> groups) {
-        return processService.getWorkItemSchemaAndPhases(process, id, taskId, 
"$taskName$", SecurityPolicy.of(user, groups));
+        return processService.getWorkItemSchemaAndPhases(process, id, taskId, 
"$taskName$", 
SecurityPolicy.of(identityProviderFactory.getOrImpersonateIdentity(user, 
groups)));
     }
 
 }
\ No newline at end of file
diff --git 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskQuarkusTemplate.java
 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskQuarkusTemplate.java
index 7369db6054..9970e3c28b 100644
--- 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskQuarkusTemplate.java
+++ 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskQuarkusTemplate.java
@@ -40,14 +40,7 @@ import jakarta.ws.rs.DELETE;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.Consumes;
 
-import org.kie.kogito.auth.IdentityProviders;
-import org.kie.kogito.auth.SecurityPolicy;
-import org.kie.kogito.process.Process;
-import org.kie.kogito.process.ProcessInstance;
-import org.kie.kogito.process.ProcessInstanceReadMode;
-import org.kie.kogito.process.WorkItem;
-import org.kie.kogito.process.impl.Sig;
-import org.kie.kogito.services.uow.UnitOfWorkExecutor;
+import org.kie.kogito.auth.IdentityProviderFactory;
 import org.kie.kogito.usertask.UserTaskInstanceNotFoundException;
 import org.kie.kogito.usertask.UserTaskService;
 import org.kie.kogito.usertask.impl.json.SimpleDeserializationProblemHandler;
@@ -75,6 +68,9 @@ public class UserTasksResource {
     @Inject
     UserTaskService userTaskService;
 
+    @Inject
+    IdentityProviderFactory identityProviderFactory;
+
     @Inject
     ObjectMapper objectMapper;
 
@@ -92,14 +88,14 @@ public class UserTasksResource {
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public List<UserTaskView> list(@QueryParam("user") String user, 
@QueryParam("group") List<String> groups) {
-        return userTaskService.list(IdentityProviders.of(user, groups));
+        return 
userTaskService.list(identityProviderFactory.getOrImpersonateIdentity(user, 
groups));
     }
 
     @GET
     @Path("/{taskId}")
     @Produces(MediaType.APPLICATION_JSON)
     public UserTaskView find(@PathParam("taskId") String taskId, 
@QueryParam("user") String user, @QueryParam("group") List<String> groups) {
-        return userTaskService.getUserTaskInstance(taskId, 
IdentityProviders.of(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
+        return userTaskService.getUserTaskInstance(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
     @POST
@@ -111,7 +107,7 @@ public class UserTasksResource {
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups,
             TransitionInfo transitionInfo) {
-        return userTaskService.transition(taskId, 
transitionInfo.getTransitionId(), transitionInfo.getData(), 
IdentityProviders.of(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
+        return userTaskService.transition(taskId, 
transitionInfo.getTransitionId(), transitionInfo.getData(), 
identityProviderFactory.getOrImpersonateIdentity(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
     @GET
@@ -121,7 +117,7 @@ public class UserTasksResource {
             @PathParam("taskId") String taskId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.allowedTransitions(taskId, 
IdentityProviders.of(user, groups));
+        return userTaskService.allowedTransitions(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups));
     }
 
     @PUT
@@ -133,7 +129,7 @@ public class UserTasksResource {
             @QueryParam("group") List<String> groups,
             String body) throws Exception {
         Map<String, Object> data = mapper.readValue(body, Map.class);
-        return userTaskService.setOutputs(taskId, data, 
IdentityProviders.of(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
+        return userTaskService.setOutputs(taskId, data, 
identityProviderFactory.getOrImpersonateIdentity(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
     @PUT
@@ -145,7 +141,7 @@ public class UserTasksResource {
             @QueryParam("group") List<String> groups,
             String body) throws Exception {
         Map<String, Object> data = mapper.readValue(body, Map.class);
-        return userTaskService.setInputs(taskId, data, 
IdentityProviders.of(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
+        return userTaskService.setInputs(taskId, data, 
identityProviderFactory.getOrImpersonateIdentity(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
     @GET
@@ -155,7 +151,7 @@ public class UserTasksResource {
             @PathParam("taskId") String taskId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.getComments(taskId, IdentityProviders.of(user, 
groups));
+        return userTaskService.getComments(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups));
     }
 
     @POST
@@ -169,7 +165,7 @@ public class UserTasksResource {
             CommentInfo commentInfo) {
         Comment comment = new Comment(null, user);
         comment.setContent(commentInfo.getComment());
-        return userTaskService.addComment(taskId, comment, 
IdentityProviders.of(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
+        return userTaskService.addComment(taskId, comment, 
identityProviderFactory.getOrImpersonateIdentity(user, 
groups)).orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
     @GET
@@ -180,7 +176,7 @@ public class UserTasksResource {
             @PathParam("commentId") String commentId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.getComment(taskId, commentId, 
IdentityProviders.of(user, groups))
+        return userTaskService.getComment(taskId, commentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(() -> new 
UserTaskInstanceNotFoundException("Comment " + commentId + " not found"));
     }
 
@@ -196,7 +192,7 @@ public class UserTasksResource {
             CommentInfo commentInfo) {
         Comment comment = new Comment(commentId, user);
         comment.setContent(commentInfo.getComment());
-        return userTaskService.updateComment(taskId, comment, 
IdentityProviders.of(user, groups))
+        return userTaskService.updateComment(taskId, comment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
@@ -207,7 +203,7 @@ public class UserTasksResource {
             @PathParam("commentId") String commentId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.removeComment(taskId, commentId, 
IdentityProviders.of(user, groups))
+        return userTaskService.removeComment(taskId, commentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
@@ -218,7 +214,7 @@ public class UserTasksResource {
             @PathParam("taskId") String taskId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.getAttachments(taskId, 
IdentityProviders.of(user, groups));
+        return userTaskService.getAttachments(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups));
     }
 
     @POST
@@ -233,7 +229,7 @@ public class UserTasksResource {
         Attachment attachment = new Attachment(null, user);
         attachment.setName(attachmentInfo.getName());
         attachment.setContent(attachmentInfo.getUri());
-        return userTaskService.addAttachment(taskId, attachment, 
IdentityProviders.of(user, groups))
+        return userTaskService.addAttachment(taskId, attachment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
@@ -250,7 +246,7 @@ public class UserTasksResource {
         Attachment attachment = new Attachment(attachmentId, user);
         attachment.setName(attachmentInfo.getName());
         attachment.setContent(attachmentInfo.getUri());
-        return userTaskService.updateAttachment(taskId, attachment, 
IdentityProviders.of(user, groups))
+        return userTaskService.updateAttachment(taskId, attachment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
@@ -261,7 +257,7 @@ public class UserTasksResource {
             @PathParam("attachmentId") String attachmentId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.removeAttachment(taskId, attachmentId, 
IdentityProviders.of(user, groups))
+        return userTaskService.removeAttachment(taskId, attachmentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(UserTaskInstanceNotFoundException::new);
     }
 
@@ -273,7 +269,7 @@ public class UserTasksResource {
             @PathParam("attachmentId") String attachmentId,
             @QueryParam("user") String user,
             @QueryParam("group") List<String> groups) {
-        return userTaskService.getAttachment(taskId, attachmentId, 
IdentityProviders.of(user, groups))
+        return userTaskService.getAttachment(taskId, attachmentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(() -> new 
UserTaskInstanceNotFoundException("Attachment " + attachmentId + " not found"));
     }
 
diff --git 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskSpringTemplate.java
 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskSpringTemplate.java
index ea5b387393..83c8bf3bbb 100644
--- 
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskSpringTemplate.java
+++ 
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/usertask/RestResourceUserTaskSpringTemplate.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 import java.util.Collection;
 
 import org.jbpm.util.JsonSchemaUtil;
-import org.kie.kogito.auth.IdentityProviders;
+import org.kie.kogito.auth.IdentityProviderFactory;
 import org.kie.kogito.auth.SecurityPolicy;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.WorkItem;
@@ -74,6 +74,9 @@ public class UserTasksResource {
     @Autowired
     UserTaskService userTaskService;
 
+    @Autowired
+    IdentityProviderFactory identityProviderFactory;
+
     @Autowired
     ObjectMapper objectMapper;
 
@@ -90,12 +93,12 @@ public class UserTasksResource {
 
     @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
     public List<UserTaskView> list(@RequestParam("user") String user, 
@RequestParam("group") List<String> groups) {
-        return userTaskService.list(IdentityProviders.of(user, groups));
+        return 
userTaskService.list(identityProviderFactory.getOrImpersonateIdentity(user, 
groups));
     }
 
     @GetMapping(value = "/{taskId}", produces = 
MediaType.APPLICATION_JSON_VALUE)
     public UserTaskView find(@PathVariable("taskId") String taskId, 
@RequestParam("user") String user, @RequestParam("group") List<String> groups) {
-        return userTaskService.getUserTaskInstance(taskId, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.getUserTaskInstance(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @PostMapping(value = "/{taskId}/transition")
@@ -104,7 +107,7 @@ public class UserTasksResource {
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups,
             @RequestBody TransitionInfo transitionInfo) {
-        return userTaskService.transition(taskId, 
transitionInfo.getTransitionId(), transitionInfo.getData(), 
IdentityProviders.of(user, groups))
+        return userTaskService.transition(taskId, 
transitionInfo.getTransitionId(), transitionInfo.getData(), 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -113,7 +116,7 @@ public class UserTasksResource {
             @PathVariable("taskId") String taskId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.allowedTransitions(taskId, 
IdentityProviders.of(user, groups));
+        return userTaskService.allowedTransitions(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups));
     }
 
     @PutMapping("/{taskId}/outputs")
@@ -123,7 +126,7 @@ public class UserTasksResource {
             @RequestParam("group") List<String> groups,
             @RequestBody String body) throws Exception {
         Map<String, Object> data = mapper.readValue(body, Map.class);
-        return userTaskService.setOutputs(taskId, data, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.setOutputs(taskId, data, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @PutMapping("/{taskId}/inputs")
@@ -133,7 +136,7 @@ public class UserTasksResource {
             @RequestParam("group") List<String> groups,
             @RequestBody String body) throws Exception {
         Map<String, Object> data = mapper.readValue(body, Map.class);
-        return userTaskService.setInputs(taskId, data, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.setInputs(taskId, data, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @GetMapping("/{taskId}/comments")
@@ -141,7 +144,7 @@ public class UserTasksResource {
             @PathVariable("taskId") String taskId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.getComments(taskId, IdentityProviders.of(user, 
groups));
+        return userTaskService.getComments(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups));
     }
 
     @PostMapping("/{taskId}/comments")
@@ -152,7 +155,7 @@ public class UserTasksResource {
             @RequestBody CommentInfo commentInfo) {
         Comment comment = new Comment(null, user);
         comment.setContent(commentInfo.getComment());
-        return userTaskService.addComment(taskId, comment, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.addComment(taskId, comment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @GetMapping("/{taskId}/comments/{commentId}")
@@ -161,7 +164,7 @@ public class UserTasksResource {
             @PathVariable("commentId") String commentId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.getComment(taskId, commentId, 
IdentityProviders.of(user, groups))
+        return userTaskService.getComment(taskId, commentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND, "Comment " + commentId + " not 
found"));
     }
 
@@ -174,7 +177,7 @@ public class UserTasksResource {
             @RequestBody CommentInfo commentInfo) {
         Comment comment = new Comment(commentId, user);
         comment.setContent(commentInfo.getComment());
-        return userTaskService.updateComment(taskId, comment, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.updateComment(taskId, comment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @DeleteMapping(value = "/{taskId}/comments/{commentId}", consumes = 
MediaType.ALL_VALUE)
@@ -183,7 +186,7 @@ public class UserTasksResource {
             @PathVariable("commentId") String commentId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.removeComment(taskId, commentId, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.removeComment(taskId, commentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @GetMapping("/{taskId}/attachments")
@@ -191,7 +194,7 @@ public class UserTasksResource {
             @PathVariable("taskId") String taskId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.getAttachments(taskId, 
IdentityProviders.of(user, groups));
+        return userTaskService.getAttachments(taskId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups));
     }
 
     @PostMapping("/{taskId}/attachments")
@@ -203,7 +206,7 @@ public class UserTasksResource {
         Attachment attachment = new Attachment(null, user);
         attachment.setName(attachmentInfo.getName());
         attachment.setContent(attachmentInfo.getUri());
-        return userTaskService.addAttachment(taskId, attachment, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.addAttachment(taskId, attachment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @PutMapping("/{taskId}/attachments/{attachmentId}")
@@ -216,7 +219,7 @@ public class UserTasksResource {
         Attachment attachment = new Attachment(attachmentId, user);
         attachment.setName(attachmentInfo.getName());
         attachment.setContent(attachmentInfo.getUri());
-        return userTaskService.updateAttachment(taskId, attachment, 
IdentityProviders.of(user, groups))
+        return userTaskService.updateAttachment(taskId, attachment, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
@@ -226,7 +229,7 @@ public class UserTasksResource {
             @PathVariable("attachmentId") String attachmentId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.removeAttachment(taskId, attachmentId, 
IdentityProviders.of(user, groups)).orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND));
+        return userTaskService.removeAttachment(taskId, attachmentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups)).orElseThrow(() 
-> new ResponseStatusException(HttpStatus.NOT_FOUND));
     }
 
     @GetMapping("/{taskId}/attachments/{attachmentId}")
@@ -235,7 +238,7 @@ public class UserTasksResource {
             @PathVariable("attachmentId") String attachmentId,
             @RequestParam("user") String user,
             @RequestParam("group") List<String> groups) {
-        return userTaskService.getAttachment(taskId, attachmentId, 
IdentityProviders.of(user, groups))
+        return userTaskService.getAttachment(taskId, attachmentId, 
identityProviderFactory.getOrImpersonateIdentity(user, groups))
                 .orElseThrow(() -> new 
ResponseStatusException(HttpStatus.NOT_FOUND, "Attachment " + attachmentId + " 
not found"));
     }
 
diff --git 
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/auth/QuarkusIdentityProviderFactoryProducer.java
 
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/auth/QuarkusIdentityProviderFactoryProducer.java
new file mode 100644
index 0000000000..ea33b3b6b8
--- /dev/null
+++ 
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/auth/QuarkusIdentityProviderFactoryProducer.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.kie.kogito.quarkus.auth;
+
+import java.util.List;
+
+import org.kie.kogito.auth.IdentityProvider;
+import org.kie.kogito.auth.IdentityProviderFactory;
+import org.kie.kogito.auth.impl.IdentityProviderFactoryImpl;
+import org.kie.kogito.auth.impl.KogitoAuthConfig;
+import org.kie.kogito.quarkus.config.KogitoRuntimeConfig;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Inject;
+
+@ApplicationScoped
+public class QuarkusIdentityProviderFactoryProducer {
+
+    private final KogitoRuntimeConfig config;
+    private final IdentityProvider identityProvider;
+
+    QuarkusIdentityProviderFactoryProducer() {
+        this(null, null);
+    }
+
+    @Inject
+    public QuarkusIdentityProviderFactoryProducer(KogitoRuntimeConfig config, 
IdentityProvider identityProvider) {
+        this.config = config;
+        this.identityProvider = identityProvider;
+    }
+
+    @Produces
+    public IdentityProviderFactory get() {
+        String[] rolesThatAllowImpersonation = 
config.authConfig.rolesThatAllowImpersonation.map(value -> 
value.split(",")).orElse(new String[] {});
+
+        return new IdentityProviderFactoryImpl(identityProvider, new 
KogitoAuthConfig(config.authConfig.enabled, 
List.of(rolesThatAllowImpersonation)));
+    }
+}
diff --git 
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
 
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoAuthRuntimeConfig.java
similarity index 57%
copy from 
quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
copy to 
quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoAuthRuntimeConfig.java
index df8e45d3ec..917439b188 100644
--- 
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
+++ 
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoAuthRuntimeConfig.java
@@ -16,33 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.kie.kogito.quarkus.config;
 
 import java.util.Optional;
 
+import io.quarkus.runtime.annotations.ConfigGroup;
 import io.quarkus.runtime.annotations.ConfigItem;
-import io.quarkus.runtime.annotations.ConfigPhase;
-import io.quarkus.runtime.annotations.ConfigRoot;
-
-@ConfigRoot(name = "", phase = ConfigPhase.RUN_TIME, prefix = "kogito")
-public class KogitoRuntimeConfig {
 
-    /**
-     * The service URL needed to connect to the runtime endpoint from outside 
the service.
-     * <p>
-     */
-    @ConfigItem(name = "service.url")
-    public Optional<String> serviceUrl;
+@ConfigGroup
+public class KogitoAuthRuntimeConfig {
 
     /**
-     * Eventing runtime configuration
+     * Enables using the application security context when resolving current 
User Identity.
      */
-    @ConfigItem(name = "quarkus.events")
-    public KogitoEventingRuntimeConfig eventingConfig;
+    @ConfigItem(name = "enabled", defaultValue = "false")
+    public boolean enabled;
 
     /**
-     * Maximum number of process instance to be returned by GET api
+     * Comma-separated list of roles that allow identity impersonation when 
resolving the actual User Identity.
      */
-    @ConfigItem(name = "process.instances.limit", defaultValue = "1000")
-    public short processInstanceLimit;
+    @ConfigItem(name = "impersonation.allowed-for-roles")
+    public Optional<String> rolesThatAllowImpersonation;
 }
diff --git 
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
 
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
index df8e45d3ec..451eae92a0 100644
--- 
a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
+++ 
b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common/src/main/java/org/kie/kogito/quarkus/config/KogitoRuntimeConfig.java
@@ -45,4 +45,10 @@ public class KogitoRuntimeConfig {
      */
     @ConfigItem(name = "process.instances.limit", defaultValue = "1000")
     public short processInstanceLimit;
+
+    /**
+     * Auth Configuration
+     */
+    @ConfigItem(name = "security.auth")
+    public KogitoAuthRuntimeConfig authConfig;
 }
diff --git 
a/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/spring/auth/SpringIdentityProviderFactoryProducer.java
 
b/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/spring/auth/SpringIdentityProviderFactoryProducer.java
new file mode 100644
index 0000000000..88e2c7cbdb
--- /dev/null
+++ 
b/springboot/starters/kogito-processes-spring-boot-starter/src/main/java/org/kie/kogito/spring/auth/SpringIdentityProviderFactoryProducer.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.kie.kogito.spring.auth;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.kie.kogito.auth.IdentityProvider;
+import org.kie.kogito.auth.IdentityProviderFactory;
+import org.kie.kogito.auth.impl.IdentityProviderFactoryImpl;
+import org.kie.kogito.auth.impl.KogitoAuthConfig;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SpringIdentityProviderFactoryProducer {
+
+    @Bean
+    public IdentityProviderFactory produce(IdentityProvider identityProvider,
+            @Value("${" + IdentityProviderFactory.KOGITO_SECURITY_AUTH_ENABLED 
+ ":false}") boolean enabled,
+            @Value("${" + 
IdentityProviderFactory.KOGITO_SECURITY_AUTH_IMPERSONATION_ALLOWED_FOR_ROLES + 
":#{null}}") Optional<String> configRolesThatAllowImpersonation) {
+        String[] rolesThatAllowImpersonation = 
configRolesThatAllowImpersonation.map(roles -> roles.split(",")).orElse(new 
String[] {});
+        return new IdentityProviderFactoryImpl(identityProvider, new 
KogitoAuthConfig(enabled, List.of(rolesThatAllowImpersonation)));
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to