|
|
@@ -8,8 +8,10 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.google.common.base.Strings;
|
|
|
import com.inspur.smsb.gateway.config.AnonymousPathProperties;
|
|
|
+import com.inspur.smsb.gateway.config.SuperAdminPathProperties;
|
|
|
import com.inspur.smsb.gateway.dto.KeycloakGroupsDto;
|
|
|
import com.inspur.smsb.gateway.dto.KeycloakUserDto;
|
|
|
+import com.inspur.smsb.gateway.utils.ExpiredMapUtil;
|
|
|
import com.inspur.smsb.gateway.utils.HttpClientUtil;
|
|
|
import com.inspur.smsb.gateway.utils.TokenParseUtil;
|
|
|
import com.nimbusds.jose.JWSObject;
|
|
|
@@ -25,6 +27,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
|
|
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.DigestUtils;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
import org.springframework.web.server.ServerWebExchange;
|
|
|
import reactor.core.publisher.Mono;
|
|
|
@@ -73,12 +76,18 @@ public class WebFluxUserRequestInfoFilter implements GlobalFilter {
|
|
|
@Value("${wxapplet.plusMinute:2}")
|
|
|
private Integer plusMinute;
|
|
|
|
|
|
+ @Value("${superadmin-path.enable:false}")
|
|
|
+ private Boolean superAdminValidate;
|
|
|
+
|
|
|
@Resource
|
|
|
private ObjectMapper objectMapper;
|
|
|
|
|
|
@Resource
|
|
|
private AnonymousPathProperties anonymousPathProperties;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private SuperAdminPathProperties superAdminPathProperties;
|
|
|
+
|
|
|
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
@Override
|
|
|
@@ -196,24 +205,24 @@ public class WebFluxUserRequestInfoFilter implements GlobalFilter {
|
|
|
}
|
|
|
// 由于漏洞扫描发现退出登陆后,token在一定时间范围内还是有效,故此处做黑名单限制,
|
|
|
// 前端退出登陆时调用下/keycloak/userLogout接口,本接口仅做token存入黑名单操作,不涉及具体业务
|
|
|
-// String logoutMd5 = DigestUtils.md5DigestAsHex(token.getBytes());
|
|
|
-// if(exchange.getRequest().getURI().getPath().contains("userLogout")) {
|
|
|
-// log.warn("user logout logout={}",logoutMd5);
|
|
|
-// ExpiredMapUtil.put(logoutMd5,logoutMd5,ExpiredMapUtil.CACHE_HOLD_TIME_5M);
|
|
|
-// }
|
|
|
-// if(Objects.nonNull(ExpiredMapUtil.get(logoutMd5))) {
|
|
|
-// ServerHttpResponse response = exchange.getResponse();
|
|
|
-// response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
|
|
-// return response.writeWith(Mono.fromSupplier(() -> {
|
|
|
-// DataBufferFactory bufferFactory = response.bufferFactory();
|
|
|
-// try {
|
|
|
-// return bufferFactory.wrap(objectMapper.writeValueAsBytes(Response.buildFailure(String.valueOf(HttpStatus.PRECONDITION_FAILED.value()), "无访问权限")));
|
|
|
-// } catch (JsonProcessingException e) {
|
|
|
-// log.error("Error writing response", e);
|
|
|
-// return bufferFactory.wrap(new byte[0]);
|
|
|
-// }
|
|
|
-// }));
|
|
|
-// }
|
|
|
+ String logoutMd5 = DigestUtils.md5DigestAsHex(token.getBytes());
|
|
|
+ if(exchange.getRequest().getURI().getPath().contains("userLogout")) {
|
|
|
+ log.warn("user logout logout={}",logoutMd5);
|
|
|
+ ExpiredMapUtil.put(logoutMd5,logoutMd5,ExpiredMapUtil.CACHE_HOLD_TIME_5M);
|
|
|
+ }
|
|
|
+ if(Objects.nonNull(ExpiredMapUtil.get(logoutMd5))) {
|
|
|
+ ServerHttpResponse response = exchange.getResponse();
|
|
|
+ response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
|
|
+ return response.writeWith(Mono.fromSupplier(() -> {
|
|
|
+ DataBufferFactory bufferFactory = response.bufferFactory();
|
|
|
+ try {
|
|
|
+ return bufferFactory.wrap(objectMapper.writeValueAsBytes(Response.buildFailure(String.valueOf(HttpStatus.PRECONDITION_FAILED.value()), "无访问权限")));
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ log.error("Error writing response", e);
|
|
|
+ return bufferFactory.wrap(new byte[0]);
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ }
|
|
|
|
|
|
String realToken = token.replace("Bearer ", "");
|
|
|
JWSObject jwsObject = JWSObject.parse(realToken);
|
|
|
@@ -233,20 +242,19 @@ public class WebFluxUserRequestInfoFilter implements GlobalFilter {
|
|
|
.header("userName", userName)
|
|
|
.header("tenant", String.valueOf(tenant))
|
|
|
.build();
|
|
|
-
|
|
|
+ // 根据token, 获取当前用户的角色 ROLE_SUPER_ADMIN -> 超管, ROLE_ADMIN -> 租户管理员,tenant已经获取,再获取org
|
|
|
+ com.nimbusds.jose.shaded.json.JSONObject realmAccess = (com.nimbusds.jose.shaded.json.JSONObject)jwsObject.getPayload().toJSONObject().get("realm_access");
|
|
|
+ com.nimbusds.jose.shaded.json.JSONArray rolesArray = (com.nimbusds.jose.shaded.json.JSONArray) realmAccess.get("roles");
|
|
|
+ List<String> roles = new ArrayList<>();
|
|
|
+ for (Object role : rolesArray) {
|
|
|
+ roles.add((String) role);
|
|
|
+ }
|
|
|
if (StringUtils.hasText(urlTenant) || StringUtils.hasText(urlOrg)) {
|
|
|
// 1、有urlOrg或者urlTenant时,才去做过滤
|
|
|
String urlRealTenant = Objects.isNull(urlTenant) ?
|
|
|
"/" + Arrays.stream(urlOrg.split("/")).filter(s -> !s.isEmpty()).collect(Collectors.toList()).get(0) : urlTenant;
|
|
|
String urlRealOrg = Objects.isNull(urlOrg) ? urlTenant : urlOrg;
|
|
|
|
|
|
- // 根据token, 获取当前用户的角色 ROLE_SUPER_ADMIN -> 超管, ROLE_ADMIN -> 租户管理员,tenant已经获取,再获取org
|
|
|
- com.nimbusds.jose.shaded.json.JSONObject realmAccess = (com.nimbusds.jose.shaded.json.JSONObject)jwsObject.getPayload().toJSONObject().get("realm_access");
|
|
|
- com.nimbusds.jose.shaded.json.JSONArray rolesArray = (com.nimbusds.jose.shaded.json.JSONArray) realmAccess.get("roles");
|
|
|
- List<String> roles = new ArrayList<>();
|
|
|
- for (Object role : rolesArray) {
|
|
|
- roles.add((String) role);
|
|
|
- }
|
|
|
// userOrg可能为空,userTenant应该是必有的
|
|
|
String userOrg = String.valueOf(jwsObject.getPayload().toJSONObject().get("org"));
|
|
|
String userTenant = tenant;
|
|
|
@@ -275,7 +283,11 @@ public class WebFluxUserRequestInfoFilter implements GlobalFilter {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ if (superAdminValidate && superAdminPathProperties.checkSuperAdminPath(request.getPath().value())) {
|
|
|
+ if (Boolean.FALSE.equals(roles.contains(ROLE_SUPER_ADMIN))) {
|
|
|
+ return getErrorResponse(exchange);
|
|
|
+ }
|
|
|
+ }
|
|
|
// 把新的 exchange 放回到过滤链
|
|
|
return chain.filter(exchange.mutate().request(request).build());
|
|
|
} catch (ParseException e) {
|