You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AEMaaCS自定义WorkflowProcess:如何获取发起者的ResourceResolver?

在AEMaaCS中实现以工作流发起者权限执行页面修改的解决方案

核心问题分析

你当前遇到的问题是:

  • 通过workflowSession获取的ResourceResolver属于workflow-process-service系统用户,无法继承发起者的权限
  • 使用USER_IMPERSONATION参数时因服务用户无模拟权限,抛出Impersonation not allowed异常
  • 无法获取发起者密码,无法通过USER参数直接登录

下面提供两种可行的解决方案,覆盖不同场景需求:


方案1:配置服务用户模拟权限,直接获取发起者ResourceResolver

这是最贴合需求的方案,通过给工作流服务用户添加模拟权限,实现以发起者身份执行操作。

步骤1:配置服务用户的模拟权限

  1. 登录AEM Author实例,进入Tools > Security > Users
  2. 找到工作流流程使用的服务用户(默认是workflow-process-service,自定义流程则找对应的系统用户)
  3. 进入用户编辑页的Permissions标签
  4. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 12:35:01