mirror of
https://gitee.com/yudaocode/yudao-boot-mini.git
synced 2026-03-22 05:27:15 +08:00
Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
This commit is contained in:
@@ -56,7 +56,14 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav
|
|||||||
protected int resolveNrOfInstances(DelegateExecution execution) {
|
protected int resolveNrOfInstances(DelegateExecution execution) {
|
||||||
// 情况一:UserTask 节点
|
// 情况一:UserTask 节点
|
||||||
if (execution.getCurrentFlowElement() instanceof UserTask) {
|
if (execution.getCurrentFlowElement() instanceof UserTask) {
|
||||||
// 获取任务的所有处理人
|
// 第一步,设置 collectionVariable 和 CollectionVariable
|
||||||
|
// 从 execution.getVariable() 读取所有任务处理人的 key
|
||||||
|
super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的
|
||||||
|
super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId());
|
||||||
|
// 从 execution.getVariable() 读取当前所有任务处理的人的 key
|
||||||
|
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
|
||||||
|
|
||||||
|
// 第二步,获取任务的所有处理人
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
|
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
|
||||||
if (assigneeUserIds == null) {
|
if (assigneeUserIds == null) {
|
||||||
|
|||||||
@@ -47,7 +47,14 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB
|
|||||||
protected int resolveNrOfInstances(DelegateExecution execution) {
|
protected int resolveNrOfInstances(DelegateExecution execution) {
|
||||||
// 情况一:UserTask 节点
|
// 情况一:UserTask 节点
|
||||||
if (execution.getCurrentFlowElement() instanceof UserTask) {
|
if (execution.getCurrentFlowElement() instanceof UserTask) {
|
||||||
// 获取任务的所有处理人
|
// 第一步,设置 collectionVariable 和 CollectionVariable
|
||||||
|
// 从 execution.getVariable() 读取所有任务处理人的 key
|
||||||
|
super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的
|
||||||
|
super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId());
|
||||||
|
// 从 execution.getVariable() 读取当前所有任务处理的人的 key
|
||||||
|
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
|
||||||
|
|
||||||
|
// 第二步,获取任务的所有处理人
|
||||||
// 不使用 execution.getVariable 原因:目前依次审批任务回退后 collectionVariable 变量没有清理, 如果重新进入该任务不会重新分配审批人
|
// 不使用 execution.getVariable 原因:目前依次审批任务回退后 collectionVariable 变量没有清理, 如果重新进入该任务不会重新分配审批人
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariableLocal(super.collectionVariable, Set.class);
|
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariableLocal(super.collectionVariable, Set.class);
|
||||||
|
|||||||
@@ -1,9 +1,107 @@
|
|||||||
package cn.iocoder.yudao.module.infra.framework.monitor.config;
|
package cn.iocoder.yudao.module.infra.framework.monitor.config;
|
||||||
|
|
||||||
import de.codecentric.boot.admin.server.config.EnableAdminServer;
|
import de.codecentric.boot.admin.server.config.EnableAdminServer;
|
||||||
|
import jakarta.servlet.DispatcherType;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
|
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Boot Admin Server 配置
|
||||||
|
*
|
||||||
|
* 包含 Admin Server 的启用配置和安全配置
|
||||||
|
* 安全配置独立于 {@link cn.iocoder.yudao.framework.security.config.YudaoWebSecurityConfigurerAdapter},
|
||||||
|
* 使用 HTTP Basic 认证保护 Admin Server 端点,不影响现有的 Token 认证机制
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableAdminServer
|
@EnableAdminServer
|
||||||
|
@ConditionalOnClass(name = "de.codecentric.boot.admin.server.config.AdminServerProperties") // 目的:按需启动 spring boot admin 监控服务
|
||||||
public class AdminServerConfiguration {
|
public class AdminServerConfiguration {
|
||||||
|
|
||||||
|
@Value("${spring.boot.admin.context-path:''}")
|
||||||
|
private String adminSeverContextPath;
|
||||||
|
|
||||||
|
@Value("${spring.boot.admin.client.username:admin}")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Value("${spring.boot.admin.client.password:admin}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Boot Admin 专用的 InMemoryUserDetailsManager
|
||||||
|
* 使用内存存储,与系统用户隔离
|
||||||
|
*/
|
||||||
|
@Bean("adminUserDetailsManager")
|
||||||
|
public InMemoryUserDetailsManager adminUserDetailsManager(PasswordEncoder passwordEncoder) {
|
||||||
|
UserDetails adminUser = User.builder()
|
||||||
|
.username(username)
|
||||||
|
.password(passwordEncoder.encode(password))
|
||||||
|
.roles("ADMIN_SERVER")
|
||||||
|
.build();
|
||||||
|
return new InMemoryUserDetailsManager(adminUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Boot Admin Server 的 SecurityFilterChain
|
||||||
|
* 使用 @Order(1) 确保优先于默认的 SecurityFilterChain 匹配
|
||||||
|
*/
|
||||||
|
@Bean("adminServerSecurityFilterChain")
|
||||||
|
@Order(1)
|
||||||
|
public SecurityFilterChain adminServerSecurityFilterChain(HttpSecurity httpSecurity,
|
||||||
|
InMemoryUserDetailsManager adminUserDetailsManager) throws Exception {
|
||||||
|
// 登录成功后的处理器
|
||||||
|
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||||
|
successHandler.setTargetUrlParameter("redirectTo");
|
||||||
|
successHandler.setDefaultTargetUrl(adminSeverContextPath + "/");
|
||||||
|
|
||||||
|
// 配置 HttpSecurity 对象
|
||||||
|
httpSecurity
|
||||||
|
// 仅匹配 Admin Server 的路径
|
||||||
|
.securityMatcher(adminSeverContextPath + "/**")
|
||||||
|
// 使用独立的 UserDetailsManager
|
||||||
|
.userDetailsService(adminUserDetailsManager)
|
||||||
|
// 授权配置
|
||||||
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
.requestMatchers(adminSeverContextPath + "/assets/**").permitAll() // 静态资源允许匿名访问
|
||||||
|
.requestMatchers(adminSeverContextPath + "/login").permitAll() // 登录页面允许匿名访问
|
||||||
|
.dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll() // 异步请求允许
|
||||||
|
.anyRequest().authenticated() // 其他请求需要认证
|
||||||
|
)
|
||||||
|
// 表单登录配置(用于 Admin UI 访问)
|
||||||
|
.formLogin(form -> form
|
||||||
|
.loginPage(adminSeverContextPath + "/login")
|
||||||
|
.successHandler(successHandler)
|
||||||
|
.permitAll()
|
||||||
|
)
|
||||||
|
// 登出配置
|
||||||
|
.logout(logout -> logout
|
||||||
|
.logoutUrl(adminSeverContextPath + "/logout")
|
||||||
|
.logoutSuccessUrl(adminSeverContextPath + "/login")
|
||||||
|
)
|
||||||
|
// HTTP Basic 认证(用于 Admin Client 注册)
|
||||||
|
.httpBasic(Customizer.withDefaults())
|
||||||
|
// CSRF 配置
|
||||||
|
.csrf(csrf -> csrf
|
||||||
|
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
|
||||||
|
.ignoringRequestMatchers(
|
||||||
|
adminSeverContextPath + "/instances", // Admin Client 注册端点忽略 CSRF
|
||||||
|
adminSeverContextPath + "/actuator/**" // Actuator 端点忽略 CSRF
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return httpSecurity.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.infra.framework.security.config;
|
package cn.iocoder.yudao.module.infra.framework.security.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
|
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
@@ -13,9 +12,6 @@ import org.springframework.security.config.annotation.web.configurers.AuthorizeH
|
|||||||
@Configuration(proxyBeanMethods = false, value = "infraSecurityConfiguration")
|
@Configuration(proxyBeanMethods = false, value = "infraSecurityConfiguration")
|
||||||
public class SecurityConfiguration {
|
public class SecurityConfiguration {
|
||||||
|
|
||||||
@Value("${spring.boot.admin.context-path:''}")
|
|
||||||
private String adminSeverContextPath;
|
|
||||||
|
|
||||||
@Bean("infraAuthorizeRequestsCustomizer")
|
@Bean("infraAuthorizeRequestsCustomizer")
|
||||||
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
|
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
|
||||||
return new AuthorizeRequestsCustomizer() {
|
return new AuthorizeRequestsCustomizer() {
|
||||||
@@ -32,9 +28,6 @@ public class SecurityConfiguration {
|
|||||||
.requestMatchers("/actuator/**").permitAll();
|
.requestMatchers("/actuator/**").permitAll();
|
||||||
// Druid 监控
|
// Druid 监控
|
||||||
registry.requestMatchers("/druid/**").permitAll();
|
registry.requestMatchers("/druid/**").permitAll();
|
||||||
// Spring Boot Admin Server 的安全配置
|
|
||||||
registry.requestMatchers(adminSeverContextPath).permitAll()
|
|
||||||
.requestMatchers(adminSeverContextPath + "/**").permitAll();
|
|
||||||
// 文件读取
|
// 文件读取
|
||||||
registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
|
registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,8 @@ spring:
|
|||||||
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
||||||
instance:
|
instance:
|
||||||
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
|
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
|
||||||
|
username: admin
|
||||||
|
password: admin
|
||||||
# Spring Boot Admin Server 服务端的相关配置
|
# Spring Boot Admin Server 服务端的相关配置
|
||||||
context-path: /admin # 配置 Spring
|
context-path: /admin # 配置 Spring
|
||||||
|
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ spring:
|
|||||||
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
|
||||||
instance:
|
instance:
|
||||||
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
|
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
|
||||||
|
username: admin
|
||||||
|
password: admin
|
||||||
# Spring Boot Admin Server 服务端的相关配置
|
# Spring Boot Admin Server 服务端的相关配置
|
||||||
context-path: /admin # 配置 Spring
|
context-path: /admin # 配置 Spring
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user