diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/security/TokenAuthenticationFilter.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/security/TokenAuthenticationFilter.java index 7d366becf..c944c18fa 100644 --- a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/security/TokenAuthenticationFilter.java +++ b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/filter/security/TokenAuthenticationFilter.java @@ -16,12 +16,14 @@ import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalance import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.time.Duration; +import java.util.Objects; import java.util.function.Function; /** @@ -43,7 +45,9 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered { /** * 空的 LoginUser 的结果 * - * TODO 芋艿:用于解决 getLoginUser 返回 Mono.empty() 的时候,会导致后续的 flatMap 无法进行处理的问题。先暂时这么解决,寻找更优解 ing + * 用于解决如下问题: + * 1. {@link #getLoginUser(ServerWebExchange, String)} 返回 Mono.empty() 时,会导致后续的 flatMap 无法进行处理的问题。 + * 2. {@link #buildUser(String)} 时,如果 Token 已经过期,返回 LOGIN_USER_EMPTY 对象,避免缓存无法刷新 */ private static final LoginUser LOGIN_USER_EMPTY = new LoginUser(); @@ -131,10 +135,19 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered { } private LoginUser buildUser(String body) { + // 处理结果,结果不正确 CommonResult result = JsonUtils.parseObject(body, CHECK_RESULT_TYPE_REFERENCE); - if (result == null || result.isError()) { + if (result == null) { return null; } + if (result.isError()) { + // 特殊情况:令牌已经过期(code = 401),需要返回 LOGIN_USER_EMPTY,避免 Token 一直因为缓存,被误判为有效 + if (Objects.equals(result.getCode(), HttpStatus.UNAUTHORIZED.value())) { + return LOGIN_USER_EMPTY; + } + return null; + } + // 创建登录用户 OAuth2AccessTokenCheckRespDTO tokenInfo = result.getData(); return new LoginUser().setId(tokenInfo.getUserId()).setUserType(tokenInfo.getUserType()) diff --git a/yudao-gateway/src/main/resources/application.yaml b/yudao-gateway/src/main/resources/application.yaml index 42f9fa5e7..15735c7d9 100644 --- a/yudao-gateway/src/main/resources/application.yaml +++ b/yudao-gateway/src/main/resources/application.yaml @@ -37,3 +37,5 @@ spring: - Path=/admin-api/bpm/** filters: - RewritePath=/admin-api/bpm/v2/api-docs, /v2/api-docs + x-forwarded: + prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀 diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/security/config/SecurityConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/security/config/SecurityConfiguration.java new file mode 100644 index 000000000..27195924a --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/security/config/SecurityConfiguration.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.bpm.framework.security.config; + +import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; +import cn.iocoder.yudao.module.system.enums.ApiConstants; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; + +/** + * System 模块的 Security 配置 + */ +@Configuration(proxyBeanMethods = false, value = "systemSecurityConfiguration") +public class SecurityConfiguration { + + @Bean("systemAuthorizeRequestsCustomizer") + public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { + return new AuthorizeRequestsCustomizer() { + + @Override + public void customize(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry) { + // TODO 芋艿:这个每个项目都需要重复配置,得捉摸有没通用的方案 + // Swagger 接口文档 + registry.antMatchers("/swagger-ui.html").anonymous() + .antMatchers("/swagger-resources/**").anonymous() + .antMatchers("/webjars/**").anonymous() + .antMatchers("/*/api-docs").anonymous(); + // Spring Boot Actuator 的安全配置 + registry.antMatchers("/actuator").anonymous() + .antMatchers("/actuator/**").anonymous(); + // RPC 服务的安全配置 + registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll(); + } + + }; + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/security/core/package-info.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/security/core/package-info.java new file mode 100644 index 000000000..6d9f5a508 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/security/core/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.bpm.framework.security.core;