From c26fabb76029870f99d499d1bb9667bcaf46aad9 Mon Sep 17 00:00:00 2001 From: yangsb Date: Mon, 22 Apr 2024 14:42:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E6=9D=83=E9=99=90=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/TokenAuthenticationFilter.java | 23 +++++++++++++++++-- .../gateway/util/SecurityFrameworkUtils.java | 5 ++++ .../system/api/oauth2/OAuth2TokenApi.java | 8 +++++++ .../system/api/oauth2/OAuth2TokenApiImpl.java | 6 +++++ .../permission/PermissionServiceImpl.java | 4 +++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/cf-gateway/src/main/java/com/cf/imes/gateway/filter/security/TokenAuthenticationFilter.java b/cf-gateway/src/main/java/com/cf/imes/gateway/filter/security/TokenAuthenticationFilter.java index e500cebec..c8c934604 100644 --- a/cf-gateway/src/main/java/com/cf/imes/gateway/filter/security/TokenAuthenticationFilter.java +++ b/cf-gateway/src/main/java/com/cf/imes/gateway/filter/security/TokenAuthenticationFilter.java @@ -23,6 +23,7 @@ import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.time.Duration; +import java.util.List; import java.util.Objects; import java.util.function.Function; @@ -70,6 +71,14 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered { }); + private final LoadingCache organIdCache = CacheUtils.buildAsyncReloadingCache(Duration.ofMinutes(1L), // 过期时间 1 分钟 + new CacheLoader<>() { + @Override + public Long load(String token) { + return getOrganIdByToken(token).block(); + } + }); + public TokenAuthenticationFilter(ReactorLoadBalancerExchangeFilterFunction lbFunction) { // Q:为什么不使用 OAuth2TokenApi 进行调用? // A1:Spring Cloud OpenFeign 官方未内置 Reactive 的支持 https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#reactive-support @@ -101,12 +110,15 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered { SecurityFrameworkUtils.setLoginUser(exchange, user); // 2.2 将 user 并设置到 login-user 的请求头,使用 json 存储值 ServerWebExchange newExchange = exchange.mutate() - .request(builder -> SecurityFrameworkUtils.setLoginUserHeader(builder, user)).build(); + .request(builder -> SecurityFrameworkUtils.setLoginUserHeader(builder, user)) + .request(builder -> SecurityFrameworkUtils.setOrganHeader(builder, user)) + .build(); return chain.filter(newExchange); }); } private Mono getLoginUser(ServerWebExchange exchange, String token) { + //Long organId = organIdCache.getIfPresent(token); // 从缓存中,获取 LoginUser Long organId = WebFrameworkUtils.getOrganId(exchange); KeyValue cacheKey = new KeyValue().setKey(organId).setValue(token); @@ -130,10 +142,17 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered { private Mono checkAccessToken(Long organId, String token) { return webClient.get() .uri(OAuth2TokenApi.URL_CHECK, uriBuilder -> uriBuilder.queryParam("accessToken", token).build()) - .headers(httpHeaders -> WebFrameworkUtils.setOrganIdHeader(organId, httpHeaders)) // 设置组织的 Header + // .headers(httpHeaders -> WebFrameworkUtils.setOrganIdHeader(organId, httpHeaders)) // 设置组织的 Header .retrieve().bodyToMono(String.class); } + private Mono getOrganIdByToken(String token) { + return webClient.get() + .uri(OAuth2TokenApi.URL_ORGAN, uriBuilder -> uriBuilder.queryParam("accessToken", token).build()) + .retrieve() + .bodyToMono(Long.class); + } + private LoginUser buildUser(String body) { // 处理结果,结果不正确 CommonResult result = JsonUtils.parseObject(body, CHECK_RESULT_TYPE_REFERENCE); diff --git a/cf-gateway/src/main/java/com/cf/imes/gateway/util/SecurityFrameworkUtils.java b/cf-gateway/src/main/java/com/cf/imes/gateway/util/SecurityFrameworkUtils.java index ebc50708a..60bc83dcc 100644 --- a/cf-gateway/src/main/java/com/cf/imes/gateway/util/SecurityFrameworkUtils.java +++ b/cf-gateway/src/main/java/com/cf/imes/gateway/util/SecurityFrameworkUtils.java @@ -25,6 +25,7 @@ public class SecurityFrameworkUtils { private static final String LOGIN_USER_ID_ATTR = "login-user-id"; private static final String LOGIN_USER_TYPE_ATTR = "login-user-type"; private static final String DATA_CODE = "data-code"; + private static final String ORGAN_ID = "organ-id"; private SecurityFrameworkUtils() {} @@ -105,4 +106,8 @@ public class SecurityFrameworkUtils { builder.header(DATA_CODE, user.getDataCode()); } + public static void setOrganHeader(ServerHttpRequest.Builder builder, LoginUser user) { + builder.header(ORGAN_ID, user.getOrganId().toString()); + } + } diff --git a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApi.java b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApi.java index c0f7e0c89..420d8f021 100644 --- a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApi.java +++ b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApi.java @@ -26,6 +26,8 @@ public interface OAuth2TokenApi { @SuppressWarnings("HttpUrlsUsage") String URL_CHECK = "http://" + ApiConstants.NAME + PREFIX + "/check"; + String URL_ORGAN = "http://" + ApiConstants.NAME + PREFIX + "/getOrganIdByToken"; + @PostMapping(PREFIX + "/create") @Operation(summary = "创建访问令牌") CommonResult createAccessToken(@Valid @RequestBody OAuth2AccessTokenCreateReqDTO reqDTO); @@ -49,4 +51,10 @@ public interface OAuth2TokenApi { CommonResult refreshAccessToken(@RequestParam("refreshToken") String refreshToken, @RequestParam("clientId") String clientId); + + @GetMapping(PREFIX + "/getOrganIdByToken") + @Operation(summary = "通过访问令牌获取组织id") + @Parameter(name = "accessToken", description = "访问令牌", required = true, example = "tudou") + CommonResult getOrganIdByToken(@RequestParam("accessToken") String accessToken); + } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApiImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApiImpl.java index d4c6d8568..91a52301f 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApiImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/oauth2/OAuth2TokenApiImpl.java @@ -63,4 +63,10 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi { return success(BeanUtils.toBean(accessTokenDO, OAuth2AccessTokenRespDTO.class)); } + @Override + public CommonResult getOrganIdByToken(String accessToken) { + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.checkAccessToken(accessToken); + return success(accessTokenDO.getOrganId()); + } + } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/permission/PermissionServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/permission/PermissionServiceImpl.java index 38d65c2f0..b7688bdc5 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/permission/PermissionServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/permission/PermissionServiceImpl.java @@ -251,7 +251,9 @@ public class PermissionServiceImpl implements PermissionService { @Cacheable(value = RedisKeyConstants.MENU_ROLE_ID_LIST, key = "#menuId") @OrganIgnore public Set getMenuRoleIdListByMenuIdFromCache1(Long menuId) { - List roleMenuDOS = roleMenuMapper.selectList(new LambdaQueryWrapperX().in(RoleMenuDO::getOrganId, 0l, OrganContextHolder.getOrganId()) + //todo 这里应该过滤组织id为0的和自己的 + List roleMenuDOS = roleMenuMapper.selectList(new LambdaQueryWrapperX() + //.in(RoleMenuDO::getOrganId, 0l, organId) .eq(RoleMenuDO::getMenuId, menuId) ); return convertSet(roleMenuDOS, RoleMenuDO::getRoleId);