package com.yunhai.flowcenter.service; import com.yunhai.flowcenter.entity.FlwInstance; import com.yunhai.flowcenter.repository.FlwInstanceRepository; import com.yunhai.flowcenter.repository.FlwTaskRepository; import com.yunhai.platform.apistd.BizException; import com.yunhai.platform.utils.exception.ErrorCode; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** Authenticated request scope; no user-supplied source/header is trusted. */ @Component @RequiredArgsConstructor public class FlowOapiSourceScope implements HandlerInterceptor { private static final String ATTRIBUTE = FlowOapiSourceScope.class.getName(); private final FlowSourcePrincipalResolver resolver; private final FlwInstanceRepository instances; private final FlwTaskRepository tasks; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String source = resolver.resolve((String) request.getAttribute("yh.app.auth")).id; request.setAttribute(ATTRIBUTE, source); String id = request.getParameter("instanceId"); java.util.regex.Matcher pathId = java.util.regex.Pattern.compile("/instance/(\\d+)(?:/|$)").matcher(request.getRequestURI()); if (id == null && pathId.find()) id = pathId.group(1); String taskId = request.getParameter("taskId"); java.util.regex.Matcher taskPath = java.util.regex.Pattern.compile("/task/(\\d+)(?:/|$)").matcher(request.getRequestURI()); if (taskId == null && taskPath.find()) taskId = taskPath.group(1); if (id != null) requireOwn(parse(id), source); if (taskId != null) { Long task = parse(taskId); requireOwn(tasks.findById(task).orElseThrow(() -> denied()).getInstanceId(), source); } return true; } private void requireOwn(Long id, String source) { FlwInstance instance = instances.findById(id).orElseThrow(() -> denied()); if (!source.equals(instance.getSourcePrincipalId())) throw denied(); } public static String current() { String source = currentOr(null); if (source == null) throw denied(); return source; } public static String currentOr(String fallback) { if (!(RequestContextHolder.getRequestAttributes() instanceof ServletRequestAttributes)) return fallback; Object value = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getAttribute(ATTRIBUTE); return value instanceof String ? (String) value : fallback; } private Long parse(String value) { try { return Long.valueOf(value); } catch (NumberFormatException e) { throw denied(); } } private static BizException denied() { return new BizException(ErrorCode.FORBIDDEN, "仅允许访问本应用来源的流程事实"); } }