AEMaaCS自定义WorkflowProcess:如何获取发起者的ResourceResolver?
在AEMaaCS中实现以工作流发起者权限执行页面修改的解决方案
核心问题分析
你当前遇到的问题是:
- 通过
workflowSession获取的ResourceResolver属于workflow-process-service系统用户,无法继承发起者的权限 - 使用
USER_IMPERSONATION参数时因服务用户无模拟权限,抛出Impersonation not allowed异常 - 无法获取发起者密码,无法通过
USER参数直接登录
下面提供两种可行的解决方案,覆盖不同场景需求:
方案1:配置服务用户模拟权限,直接获取发起者ResourceResolver
这是最贴合需求的方案,通过给工作流服务用户添加模拟权限,实现以发起者身份执行操作。
步骤1:配置服务用户的模拟权限
- 登录AEM Author实例,进入
Tools > Security > Users - 找到工作流流程使用的服务用户(默认是
workflow-process-service,自定义流程则找对应的系统用户) - 进入用户编辑页的
Permissions标签 - 在
User Administration分类下,勾选Impersonate Users权限,并指定允许模拟的用户组(比如发起者所在的contributor组)或单个用户
步骤2:修改代码实现发起者身份操作
使用USER_IMPERSONATION参数获取发起者的ResourceResolver,并通过try-with-resources自动管理资源:
import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import com.adobe.granite.workflow.exec.WorkItem; import com.adobe.granite.workflow.exec.WorkflowProcess; import com.adobe.granite.workflow.metadata.MetaDataMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; import javax.jcr.LoginException; @Component(service = WorkflowProcess.class, property = { "process.label=自定义页面修改流程" }) public class CustomPageModifyProcess implements WorkflowProcess { private static final Logger log = LoggerFactory.getLogger(CustomPageModifyProcess.class); @Reference private ResourceResolverFactory resourceResolverFactory; @Override public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) { String initiator = workItem.getWorkflow().getInitiator(); String pagePath = metaDataMap.get("targetPagePath", String.class); Map<String, Object> authInfo = new HashMap<>(); authInfo.put(ResourceResolverFactory.USER_IMPERSONATION, initiator); // 自动关闭ResourceResolver,避免资源泄漏 try (ResourceResolver initiatorResolver = resourceResolverFactory.getResourceResolver(authInfo)) { // 双重验证发起者的修改权限 if (initiatorResolver.hasPermission(pagePath, "modify")) { // 执行页面修改逻辑 PageManager pageManager = initiatorResolver.adaptTo(PageManager.class); Page targetPage = pageManager.getPage(pagePath); if (targetPage != null) { Map<String, Object> updateProps = new HashMap<>(); updateProps.put("customStatus", "processed"); pageManager.updatePageProperties(targetPage, updateProps, false); log.info("以发起者{}身份完成页面{}修改", initiator, pagePath); } else { log.error("目标页面{}不存在", pagePath); } } else { log.warn("发起者{}无页面{}的修改权限", initiator, pagePath); // 可抛出工作流异常终止流程 } } catch (LoginException e) { log.error("模拟发起者{}失败:{}", initiator, e.getMessage(), e); } } }
方案2:验证发起者权限后用服务用户执行修改
如果因安全限制无法配置模拟权限,可以先验证发起者的权限,再用服务用户执行修改操作。
代码实现
@Override public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) { String initiator = workItem.getWorkflow().getInitiator(); String pagePath = metaDataMap.get("targetPagePath", String.class); // 使用服务用户身份获取ResourceResolver(需提前配置服务用户映射) Map<String, Object> systemAuth = new HashMap<>(); systemAuth.put(ResourceResolverFactory.SUBSERVICE, "workflow-modify-service"); try (ResourceResolver systemResolver = resourceResolverFactory.getResourceResolver(systemAuth)) { UserManager userManager = systemResolver.adaptTo(UserManager.class); Authorizable initiatorUser = userManager.getAuthorizable(initiator); if (initiatorUser == null) { log.error("发起者用户{}不存在", initiator); return; } // 验证发起者对目标页面的修改权限 AccessControlManager acm = systemResolver.adaptTo(AccessControlManager.class); boolean hasModifyPerm = acm.hasPermission(pagePath, "modify"); if (!hasModifyPerm) { log.warn("发起者{}无页面{}修改权限", initiator, pagePath); return; } // 服务用户执行修改(需确保服务用户有页面修改权限) PageManager pageManager = systemResolver.adaptTo(PageManager.class); Page targetPage = pageManager.getPage(pagePath); if (targetPage != null) { Map<String, Object> updateProps = new HashMap<>(); updateProps.put("customStatus", "processed"); pageManager.updatePageProperties(targetPage, updateProps, false); log.info("验证发起者权限后完成页面{}修改", pagePath); } } catch (LoginException | RepositoryException e) { log.error("操作失败:{}", e.getMessage(), e); } }
配套配置
需要在项目的服务用户映射配置文件(/apps/your-project/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-your-project.cfg.json)中添加映射:
{ "user.mapping": [ "com.yourcompany.core.workflow.CustomPageModifyProcess=workflow-process-service" ] }
内容的提问来源于stack exchange,提问作者Dr. Hans-Peter Störrr
相关产品推荐
相关产品推荐

