Files
flow-center-service/src/main/java/com/yunhai/flowcenter/service/FlowOapiSourceScope.java
T

63 lines
3.1 KiB
Java

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, "仅允许访问本应用来源的流程事实"); }
}