Browse Source

越权问题处理

master
wangxianzhang 3 years ago
parent
commit
99f6995d00
  1. 2
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/HasOperPermissionFormDTO.java
  2. 2
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonOperAccessOpenFeignClient.java
  3. 26
      epmet-gateway/src/main/java/com/epmet/GatewayApplication.java
  4. 11
      epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java
  5. 11
      epmet-gateway/src/main/java/com/epmet/filter/CpProperty.java
  6. 5
      epmet-gateway/src/main/java/com/epmet/filter/EpmetGatewayFilter.java
  7. 5
      epmet-gateway/src/main/resources/bootstrap-urls.yml
  8. 1
      epmet-gateway/src/main/resources/bootstrap.yml
  9. 2
      epmet-module/oper-access/oper-access-client/src/main/java/com/epmet/dto/form/HasOperPermissionFormDTO.java
  10. 13
      epmet-module/oper-access/oper-access-server/src/main/java/com/epmet/controller/OperMenuController.java
  11. 4
      epmet-module/oper-access/oper-access-server/src/main/java/com/epmet/redis/OperMenuRedis.java

2
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/HasOperPermissionFormDTO.java

@ -19,4 +19,6 @@ public class HasOperPermissionFormDTO {
@NotBlank(message = "请求http方法不能为空")
private String method;
@NotBlank(message = "操作者ID不能为空")
private String operId;
}

2
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/feign/CommonOperAccessOpenFeignClient.java

@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RequestBody;
* @Author yinzuomei
* @Date 2020/5/21 15:17 本服务对外开放的API,其他服务通过引用此client调用该服务
*/
// , url = "http://localhost:8093"
@FeignClient(name = ServiceConstant.OPER_ACCESS_SERVER, fallbackFactory = CommonOperAccessOpenFeignClientFallbackFactory.class)
//@FeignClient(name = ServiceConstant.OPER_ACCESS_SERVER, fallbackFactory = CommonOperAccessOpenFeignClientFallbackFactory.class, url = "http://localhost:8093")
public interface CommonOperAccessOpenFeignClient {
/**
* @param

26
epmet-gateway/src/main/java/com/epmet/GatewayApplication.java

@ -8,9 +8,15 @@
package com.epmet;
import com.alibaba.fastjson.JSON;
import com.epmet.commons.tools.aspect.ServletExceptionHandler;
import com.epmet.commons.tools.config.RedissonConfig;
import com.epmet.commons.tools.config.ThreadDispatcherConfig;
import com.epmet.commons.tools.redis.RedisKeys;
import com.epmet.commons.tools.redis.RedisUtils;
import com.epmet.filter.CpProperty;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@ -18,6 +24,9 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 网关服务
*
@ -31,7 +40,24 @@ import org.springframework.context.annotation.FilterType;
@ComponentScan(basePackages = {"com.epmet.*"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {RedissonConfig.class, ThreadDispatcherConfig.class, ServletExceptionHandler.class}))
public class GatewayApplication {
@Autowired
private CpProperty cpProperty;
@Autowired
private RedisUtils redisUtils;
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
/**
* 初始化运营端校验资源列表
*/
@PostConstruct
public void initOperExamineResources() {
if (!redisUtils.hasKey(RedisKeys.getOperExamineResourceUrls())) {
List<CpProperty.OperExamineResource> operExamineResourceUrls = cpProperty.getOperExamineResourceUrls();
redisUtils.setString(RedisKeys.getOperExamineResourceUrls(), JSON.toJSONString(operExamineResourceUrls));
}
}
}

11
epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java

@ -124,7 +124,7 @@ public class InternalAuthProcessor extends AuthProcessor {
// 针对运营端的url拦截和校验
if (AppClientConstant.APP_OPER.equals(app)) {
HttpMethod method = request.getMethod();
Boolean hasAccess = checkRequestOperResource(requestUri, method.toString());
Boolean hasAccess = checkRequestOperResource(userId, requestUri, method.toString());
if (!hasAccess) {
throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "资源未授权", "资源未授权");
}
@ -140,10 +140,14 @@ public class InternalAuthProcessor extends AuthProcessor {
* @param method
* @return
*/
private Boolean checkRequestOperResource(String uri, String method) {
String resourceJsonString = (String)redisUtils.get(RedisKeys.getOperExamineResourceUrls());
private Boolean checkRequestOperResource(String userId, String uri, String method) {
String resourceJsonString = redisUtils.getString(RedisKeys.getOperExamineResourceUrls());
List<OperResouce> resources = JSON.parseObject(resourceJsonString, new TypeReference<List<OperResouce>>() {});
if (resources == null) {
return true;
}
for (OperResouce resource : resources) {
if (antPathMatcher.match(resource.getResourceUrl(), uri)
&& resource.getResourceMethod().equals(method)) {
@ -152,6 +156,7 @@ public class InternalAuthProcessor extends AuthProcessor {
HasOperPermissionFormDTO form = new HasOperPermissionFormDTO();
form.setUri(uri);
form.setMethod(method);
form.setOperId(userId);
Result result = operAccessOpenFeignClient.hasOperPermission(form);
if (result == null || !result.success()) {
return false;

11
epmet-gateway/src/main/java/com/epmet/filter/CpProperty.java

@ -42,4 +42,15 @@ public class CpProperty {
*/
private List<String> swaggerUrls;
/**
* 运营端需要校验的url资源列表
*/
private List<OperExamineResource> operExamineResourceUrls;
@Data
public static class OperExamineResource {
private String resourceUrl;
private String resourceMethod;
}
}

5
epmet-gateway/src/main/java/com/epmet/filter/EpmetGatewayFilter.java

@ -5,6 +5,7 @@ import com.epmet.auth.ExternalAuthProcessor;
import com.epmet.auth.InternalAuthProcessor;
import com.epmet.commons.tools.constant.AppClientConstant;
import com.epmet.commons.tools.exception.EpmetErrorCode;
import com.epmet.commons.tools.exception.EpmetException;
import com.epmet.commons.tools.exception.ExceptionUtils;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.utils.IpUtils;
@ -64,6 +65,10 @@ public class EpmetGatewayFilter implements GatewayFilter {
}
return doFilter(exchange, chain);
} catch (EpmetException re) {
// 人为抛出,则携带错误码和错误信息响应给前端
log.error("EpmetGatewayFilter认证出错RenException,错误信息:{}", ExceptionUtils.getErrorStackTrace(re));
return response(exchange, new Result<>().error(re.getCode(), re.getMessage()));
} catch (RenException re) {
// 人为抛出,则携带错误码和错误信息响应给前端
log.error("EpmetGatewayFilter认证出错RenException,错误信息:{}", ExceptionUtils.getErrorStackTrace(re));

5
epmet-gateway/src/main/resources/bootstrap-urls.yml

@ -0,0 +1,5 @@
epmet:
oper-examine-resource-urls:
# 角色编辑
- resourceUrl: /oper/access/operrole
resourceMethod: PUT

1
epmet-gateway/src/main/resources/bootstrap.yml

@ -12,6 +12,7 @@ spring:
name: epmet-gateway-server
#环境 dev|test|prod
profiles:
include: urls
active: @spring.profiles.active@
messages:
encoding: UTF-8

2
epmet-module/oper-access/oper-access-client/src/main/java/com/epmet/dto/form/HasOperPermissionFormDTO.java

@ -19,4 +19,6 @@ public class HasOperPermissionFormDTO {
@NotBlank(message = "请求http方法不能为空")
private String method;
@NotBlank(message = "操作者ID不能为空")
private String operId;
}

13
epmet-module/oper-access/oper-access-server/src/main/java/com/epmet/controller/OperMenuController.java

@ -175,15 +175,12 @@ public class OperMenuController {
String uri = form.getUri();
String method = form.getMethod();
String loginUserApp = EpmetRequestHolder.getLoginUserApp();
String loginUserId = EpmetRequestHolder.getLoginUserId();
// if (!AppClientConstant.APP_OPER.equals(loginUserApp)) {
//// 只校验运营端,其他都返回true
// return new Result();
// }
if (!AppClientConstant.APP_OPER.equals(loginUserApp)) {
// 只校验运营端,其他都返回true
return new Result();
}
Boolean isMathe = operMenuService.hasOperPermission(uri, method, loginUserId);
Boolean isMathe = operMenuService.hasOperPermission(uri, method, form.getOperId());
if (isMathe){
return new Result();
} else {

4
epmet-module/oper-access/oper-access-server/src/main/java/com/epmet/redis/OperMenuRedis.java

@ -76,14 +76,14 @@ public class OperMenuRedis {
public List<OperResouce> getOperResourcesByUserId(String operId) {
String key = RedisKeys.operResourcesByUserId(operId);
String json = (String) redisUtils.get(key);
String json = redisUtils.getString(key);
return JSON.parseObject(json, new TypeReference<List<OperResouce>>(){});
}
public void setOperResourcesByUserId(String operId, List<OperResouce> resouces) {
String key = RedisKeys.operResourcesByUserId(operId);
String jsonString = JSON.toJSONString(resouces);
redisUtils.set(key, jsonString);
redisUtils.setString(key, jsonString);
}
/**

Loading…
Cancel
Save