Browse Source

增加跨域配置,db:epmet_admin.cors_config

dev
wxz 4 years ago
parent
commit
cde9fa4bb6
  1. 20
      epmet-admin/epmet-admin-client/src/main/java/com/epmet/dto/result/CorsConfigResultDTO.java
  2. 24
      epmet-admin/epmet-admin-client/src/main/java/com/epmet/feign/EpmetAdminOpenFeignClient.java
  3. 18
      epmet-admin/epmet-admin-client/src/main/java/com/epmet/feign/fallback/EpmetAdminOpenFeignClientFallback.java
  4. 32
      epmet-admin/epmet-admin-server/src/main/java/com/epmet/controller/CorsConfigController.java
  5. 33
      epmet-admin/epmet-admin-server/src/main/java/com/epmet/dao/CorsConfigDao.java
  6. 51
      epmet-admin/epmet-admin-server/src/main/java/com/epmet/entity/CorsConfigEntity.java
  7. 14
      epmet-admin/epmet-admin-server/src/main/java/com/epmet/service/CorsConfigService.java
  8. 36
      epmet-admin/epmet-admin-server/src/main/java/com/epmet/service/impl/CorsConfigServiceImpl.java
  9. 19
      epmet-admin/epmet-admin-server/src/main/resources/mapper/CorsConfigDao.xml
  10. 10
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java
  11. 5
      epmet-gateway/pom.xml
  12. 21
      epmet-gateway/src/main/java/com/epmet/bean/CorsConfigCache.java
  13. 97
      epmet-gateway/src/main/java/com/epmet/config/CorsConfig.java

20
epmet-admin/epmet-admin-client/src/main/java/com/epmet/dto/result/CorsConfigResultDTO.java

@ -0,0 +1,20 @@
package com.epmet.dto.result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CorsConfigResultDTO {
/**
* 首部类型
*/
private String headerType;
/**
* 首部值
*/
private String headerValue;
}

24
epmet-admin/epmet-admin-client/src/main/java/com/epmet/feign/EpmetAdminOpenFeignClient.java

@ -0,0 +1,24 @@
package com.epmet.feign;
import com.epmet.commons.tools.constant.ServiceConstant;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.result.CorsConfigResultDTO;
import com.epmet.feign.fallback.EpmetAdminOpenFeignClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
@FeignClient(name = ServiceConstant.EPMET_ADMIN_SERVER, fallback = EpmetAdminOpenFeignClientFallback.class)
//@FeignClient(name = ServiceConstant.EPMET_ADMIN_SERVER, fallback = EpmetAdminOpenFeignClientFallback.class, url = "localhost:8082")
public interface EpmetAdminOpenFeignClient {
/**
* @Description 查询跨域配置列表
* @return
* @author wxz
* @date 2021.06.25 10:00
*/
@PostMapping("/sys/cors-config/list")
Result<List<CorsConfigResultDTO>> list();
}

18
epmet-admin/epmet-admin-client/src/main/java/com/epmet/feign/fallback/EpmetAdminOpenFeignClientFallback.java

@ -0,0 +1,18 @@
package com.epmet.feign.fallback;
import com.epmet.commons.tools.constant.ServiceConstant;
import com.epmet.commons.tools.utils.ModuleUtils;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.result.CorsConfigResultDTO;
import com.epmet.feign.EpmetAdminOpenFeignClient;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class EpmetAdminOpenFeignClientFallback implements EpmetAdminOpenFeignClient {
@Override
public Result<List<CorsConfigResultDTO>> list() {
return ModuleUtils.feignConError(ServiceConstant.EPMET_USER_SERVER, "list", null);
}
}

32
epmet-admin/epmet-admin-server/src/main/java/com/epmet/controller/CorsConfigController.java

@ -0,0 +1,32 @@
package com.epmet.controller;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.result.CorsConfigResultDTO;
import com.epmet.service.CorsConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("cors-config")
public class CorsConfigController {
@Autowired
private CorsConfigService corsConfigService;
/**
* @Description 查询跨域配置列表
* @return
* @author wxz
* @date 2021.06.25 10:00
*/
@PostMapping("/list")
public Result<List<CorsConfigResultDTO>> list() {
List<CorsConfigResultDTO> list = corsConfigService.list();
return new Result<List<CorsConfigResultDTO>>().ok(list);
}
}

33
epmet-admin/epmet-admin-server/src/main/java/com/epmet/dao/CorsConfigDao.java

@ -0,0 +1,33 @@
/**
* Copyright 2018 人人开源 https://www.renren.io
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.epmet.dao;
import com.epmet.commons.mybatis.dao.BaseDao;
import com.epmet.entity.CorsConfigEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 跨域配置表
*
* @author generator generator@elink-cn.com
* @since v1.0.0 2021-06-25
*/
@Mapper
public interface CorsConfigDao extends BaseDao<CorsConfigEntity> {
}

51
epmet-admin/epmet-admin-server/src/main/java/com/epmet/entity/CorsConfigEntity.java

@ -0,0 +1,51 @@
/**
* Copyright 2018 人人开源 https://www.renren.io
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.epmet.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.epmet.commons.mybatis.entity.BaseEpmetEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 跨域配置表
*
* @author generator generator@elink-cn.com
* @since v1.0.0 2021-06-25
*/
@Data
@EqualsAndHashCode(callSuper=false)
@TableName("cors_config")
public class CorsConfigEntity extends BaseEpmetEntity {
private static final long serialVersionUID = 1L;
/**
* 首部类型
*/
private String headerType;
/**
* 首部值
*/
private String headerValue;
}

14
epmet-admin/epmet-admin-server/src/main/java/com/epmet/service/CorsConfigService.java

@ -0,0 +1,14 @@
package com.epmet.service;
import com.epmet.dto.result.CorsConfigResultDTO;
import java.util.List;
/**
* @Description 跨域配置service接口
* @author wxz
* @date 2021-06-44 09:52:44
*/
public interface CorsConfigService {
List<CorsConfigResultDTO> list();
}

36
epmet-admin/epmet-admin-server/src/main/java/com/epmet/service/impl/CorsConfigServiceImpl.java

@ -0,0 +1,36 @@
package com.epmet.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.epmet.commons.tools.utils.ConvertUtils;
import com.epmet.dao.CorsConfigDao;
import com.epmet.dto.result.CorsConfigResultDTO;
import com.epmet.entity.CorsConfigEntity;
import com.epmet.service.CorsConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description 跨域配置
* @author wxz
* @date 2021.06.25 09:53:57
*/
@Service
public class CorsConfigServiceImpl implements CorsConfigService {
@Autowired
private CorsConfigDao corsConfigDao;
/**
* @Description 查询配置列表
* @return
* @author wxz
* @date 2021.06.25 09:58
*/
@Override
public List<CorsConfigResultDTO> list() {
LambdaQueryWrapper<CorsConfigEntity> conditions = new LambdaQueryWrapper<>();
return ConvertUtils.sourceToTarget(corsConfigDao.selectList(conditions), CorsConfigResultDTO.class);
}
}

19
epmet-admin/epmet-admin-server/src/main/resources/mapper/CorsConfigDao.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.epmet.dao.CorsConfigDao">
<resultMap type="com.epmet.entity.CorsConfigEntity" id="corsConfigMap">
<result property="id" column="ID"/>
<result property="headerType" column="HEADER_TYPE"/>
<result property="headerValue" column="HEADER_VALUE"/>
<result property="delFlag" column="DEL_FLAG"/>
<result property="revision" column="REVISION"/>
<result property="createdBy" column="CREATED_BY"/>
<result property="createdTime" column="CREATED_TIME"/>
<result property="updatedBy" column="UPDATED_BY"/>
<result property="updatedTime" column="UPDATED_TIME"/>
</resultMap>
</mapper>

10
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java

@ -459,4 +459,14 @@ public class RedisKeys {
String currentMonth= DateUtils.getBeforeNMonth(NumConstant.ZERO);
return "groupread:user:".concat(currentMonth).concat(":").concat(source).concat(":").concat(groupId).concat(":").concat(sourceId);
}
/**
* @Description 跨域配置key
* @return
* @author wxz
* @date 2021.06.25 10:31
*/
public static String getCorsConfigKey() {
return rootPrefix.concat("sys:cors");
}
}

5
epmet-gateway/pom.xml

@ -81,6 +81,11 @@
<artifactId>epmet-commons-openapi</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.epmet</groupId>
<artifactId>epmet-admin-client</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
<build>

21
epmet-gateway/src/main/java/com/epmet/bean/CorsConfigCache.java

@ -0,0 +1,21 @@
package com.epmet.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @Description 跨域配置缓存
* @author wxz
* @date 2021.06.25 10:59:44
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CorsConfigCache {
private List<String> accessControlAllowOrigins;
}

97
epmet-gateway/src/main/java/com/epmet/config/CorsConfig.java

@ -1,15 +1,29 @@
/**
* Copyright (c) 2018 人人开源 All rights reserved.
*
* <p>
* https://www.renren.io
*
* <p>
* 版权所有侵权必究
*/
package com.epmet.config;
import com.epmet.bean.CorsConfigCache;
import com.epmet.commons.tools.constant.ServiceConstant;
import com.epmet.commons.tools.exception.EpmetErrorCode;
import com.epmet.commons.tools.exception.ExceptionUtils;
import com.epmet.commons.tools.feign.ResultDataResolver;
import com.epmet.commons.tools.redis.RedisKeys;
import com.epmet.dto.result.CorsConfigResultDTO;
import com.epmet.feign.EpmetAdminOpenFeignClient;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@ -21,6 +35,11 @@ import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Cors跨域
*
@ -29,11 +48,33 @@ import reactor.core.publisher.Mono;
*/
@Configuration
public class CorsConfig {
private static final String MAX_AGE = "18000L";
@Bean
public WebFilter corsFilter() {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
return new EpmetWebFilter();
}
}
/**
* @Description 用于CORS等操作的判断
* @return
* @author wxz
* @date 2021.06.25 10:42
*/
class EpmetWebFilter implements WebFilter, ResultDataResolver {
private static final String MAX_AGE = "18000L";
@Autowired
private EpmetAdminOpenFeignClient adminOpenFeignClient;
@Resource
private RedisTemplate<String, CorsConfigCache> redisTemplate;
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public Mono<Void> filter(ServerWebExchange ctx, WebFilterChain chain) {
ServerHttpRequest request = ctx.getRequest();
if (!CorsUtils.isCorsRequest(request)) {
return chain.filter(ctx);
@ -42,7 +83,9 @@ public class CorsConfig {
ServerHttpResponse response = ctx.getResponse();
HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();
HttpHeaders headers = response.getHeaders();
if (isAllowed(requestHeaders.getOrigin())) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());
}
headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());
if (requestMethod != null) {
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());
@ -55,7 +98,51 @@ public class CorsConfig {
return Mono.empty();
}
return chain.filter(ctx);
};
}
/**
* @Description 是否允许跨域
* @return
* @author wxz
* @date 2021.06.25 10:43
*/
private Boolean isAllowed(String origin) {
HashOperations<String, String, List<String>> ope = redisTemplate.opsForHash();
Map<String, List<String>> configMap = ope.entries(RedisKeys.getCorsConfigKey());
if (configMap == null || configMap.size() == 0) {
List<CorsConfigResultDTO> data = null;
try {
data = getResultDataOrThrowsException(
adminOpenFeignClient.list(),
ServiceConstant.EPMET_ADMIN_SERVER,
EpmetErrorCode.SERVER_ERROR.getCode(),
"调用Admin服务查询Cors配置失败");
} catch (Exception e) {
logger.error("调用Admin服务查询Cors配置失败");
}
// 将origin集合
List<String> origins = data.stream()
.filter((c) -> HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN.equals(c.getHeaderType()))
.map((c) -> c.getHeaderValue())
.collect(Collectors.toList());
try {
configMap.put(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origins);
ope.putAll(RedisKeys.getCorsConfigKey(), configMap);
} catch (Exception e) {
logger.error(String.format("gateway缓存跨域配置出错:%s", ExceptionUtils.getErrorStackTrace(e)));
}
}
List<String> accessControlAllowOrigins = configMap.get(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN);
if (CollectionUtils.isEmpty(accessControlAllowOrigins)) {
return false;
}
if (accessControlAllowOrigins.contains("*")) {
return true;
}
return accessControlAllowOrigins.contains(origin);
}
}
Loading…
Cancel
Save