diff --git a/epmet-gateway/src/main/java/com/epmet/auth/ExternalAuthProcessor.java b/epmet-gateway/src/main/java/com/epmet/auth/ExternalAuthProcessor.java index c2614b488a..baf5151766 100644 --- a/epmet-gateway/src/main/java/com/epmet/auth/ExternalAuthProcessor.java +++ b/epmet-gateway/src/main/java/com/epmet/auth/ExternalAuthProcessor.java @@ -4,13 +4,16 @@ import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.ExceptionUtils; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.utils.Result; +import com.epmet.filter.CpProperty; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.http.HttpHeaders; +import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @@ -41,9 +44,30 @@ public class ExternalAuthProcessor extends AuthProcessor { @Autowired private ExtAppMD5AuthProcessor md5AuthProcessor; + private final AntPathMatcher antPathMatcher = new AntPathMatcher(); + + @Autowired + private CpProperty cpProperty; + @Override public Mono auth(ServerWebExchange exchange, GatewayFilterChain chain) { - HttpHeaders headers = exchange.getRequest().getHeaders(); + ServerHttpRequest request = exchange.getRequest(); + + // 只有在外部应用urls中的url才会允许外部应用访问,否则不允许访问 + String requestUri = request.getPath().pathWithinApplication().value(); + + boolean inPaths = false; + for (String url : cpProperty.getExternalOpenUrls()) { + if (antPathMatcher.match(url, requestUri)) { + inPaths = true; + } + } + + if (!inPaths) { + throw new RenException(EpmetErrorCode.ERR401.getCode(), "所请求的url并未对外部应用开放"); + } + + HttpHeaders headers = request.getHeaders(); String token = headers.getFirst(ACCESS_TOKEN_HEADER_KEY); String appId = headers.getFirst(APP_ID_HEADER_KEY); @@ -52,7 +76,7 @@ public class ExternalAuthProcessor extends AuthProcessor { String authType = headers.getFirst(APP_ID_AUTY_TYPE_KEY); if (StringUtils.isAnyBlank(token, appId)) { - throw new RenException("请求头中的AccessToken和AppId不能为空"); + throw new RenException(EpmetErrorCode.ERR401.getCode(), "请求头中的AccessToken和AppId不能为空"); } logger.info("外部应用请求认证拦截Aspect执行,appId:{}, token:{}, ts:{}, customerId:{}, authType:{}", @@ -65,7 +89,7 @@ public class ExternalAuthProcessor extends AuthProcessor { } else if (APP_AUTH_TYPE_MD5.equals(authType)) { md5AuthProcessor.auth(appId, token, StringUtils.isNotBlank(ts) ? new Long(ts) : null, exchange); } else { - throw new RenException(EpmetErrorCode.OPER_EXTERNAL_APP_AUTH_ERROR.getCode(), "未知的认证类型"); + throw new RenException(EpmetErrorCode.OPER_EXTERNAL_APP_AUTH_ERROR.getCode(), "未知的外部认证类型"); } } catch (RenException e) { return response(exchange, new Result<>().error(e.getCode(), e.getMsg())); diff --git a/epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java b/epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java index ee247c843b..c87f9dbe6b 100644 --- a/epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java +++ b/epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java @@ -9,6 +9,7 @@ import com.epmet.commons.tools.security.dto.GovTokenDto; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.CpUserDetailRedis; import com.epmet.commons.tools.utils.Result; +import com.epmet.filter.CpProperty; import com.epmet.jwt.JwtTokenUtils; import io.jsonwebtoken.Claims; import org.apache.commons.lang3.StringUtils; @@ -19,6 +20,7 @@ import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.http.HttpHeaders; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @@ -36,6 +38,11 @@ public class InternalAuthProcessor extends AuthProcessor { @Autowired private CpUserDetailRedis cpUserDetailRedis; + private final AntPathMatcher antPathMatcher = new AntPathMatcher(); + + @Autowired + private CpProperty cpProperty; + @Override public Mono auth(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); @@ -82,14 +89,16 @@ public class InternalAuthProcessor extends AuthProcessor { } } - // 校验token - if (StringUtils.isBlank(token)) { - return response(exchange,new Result<>().error(EpmetErrorCode.ERR10005.getCode(),EpmetErrorCode.ERR10005.getMsg())); - } - try { - validateTokenDto(baseTokenDto, token); - } catch (RenException e) { - return response(exchange,new Result<>().error(e.getCode(),e.getMsg())); + if (needAuth(requestUri)) { + // 校验token + if (StringUtils.isBlank(token)) { + return response(exchange, new Result<>().error(EpmetErrorCode.ERR10005.getCode(), EpmetErrorCode.ERR10005.getMsg())); + } + try { + validateTokenDto(baseTokenDto, token); + } catch (RenException e) { + return response(exchange, new Result<>().error(e.getCode(), e.getMsg())); + } } // 添加header @@ -116,6 +125,20 @@ public class InternalAuthProcessor extends AuthProcessor { return chain.filter(exchange); } + /** + * 是否需要认证 + * @param requestUri + * @return + */ + private boolean needAuth(String requestUri) { + for (String url : cpProperty.getInternalAuthUrls()) { + if (antPathMatcher.match(url, requestUri)) { + return true; + } + } + return false; + } + /** * 从请求中获取token * @param request diff --git a/epmet-gateway/src/main/java/com/epmet/constant/AuthTypeConstant.java b/epmet-gateway/src/main/java/com/epmet/constant/AuthTypeConstant.java new file mode 100644 index 0000000000..d2123966f6 --- /dev/null +++ b/epmet-gateway/src/main/java/com/epmet/constant/AuthTypeConstant.java @@ -0,0 +1,8 @@ +package com.epmet.constant; + +public class AuthTypeConstant { + public static final String AUTH_TYPE_INTERNAL = "internal"; + public static final String AUTH_TYPE_EXTERNAL = "external"; + public static final String AUTH_TYPE_NO_NEED = "no_need"; + public static final String AUTH_TYPE_UNKNOW = "unknow"; +} diff --git a/epmet-gateway/src/main/java/com/epmet/constant/TokenHeaderKeyConstant.java b/epmet-gateway/src/main/java/com/epmet/constant/TokenHeaderKeyConstant.java new file mode 100644 index 0000000000..e7ad2adecd --- /dev/null +++ b/epmet-gateway/src/main/java/com/epmet/constant/TokenHeaderKeyConstant.java @@ -0,0 +1,6 @@ +package com.epmet.constant; + +public class TokenHeaderKeyConstant { + public static final String ACCESS_TOKEN_HEADER_KEY = "AccessToken"; + public static final String AUTHORIZATION_TOKEN_HEADER_KEY = "Authorization"; +} diff --git a/epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java b/epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java index 59f52483b2..971f4938b1 100644 --- a/epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java +++ b/epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java @@ -7,7 +7,10 @@ import com.epmet.auth.InternalAuthProcessor; import com.epmet.commons.tools.constant.AppClientConstant; import com.epmet.commons.tools.constant.Constant; import com.epmet.commons.tools.exception.EpmetErrorCode; +import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.utils.Result; +import com.epmet.constant.AuthTypeConstant; +import com.epmet.constant.TokenHeaderKeyConstant; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,16 +43,6 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory().error(EpmetErrorCode.ERR401.getCode(), - EpmetErrorCode.ERR401.getMsg())); + try { + switch (authType) { + case AuthTypeConstant.AUTH_TYPE_EXTERNAL: + return externalAuthProcessor.auth(exchange, chain); + case AuthTypeConstant.AUTH_TYPE_INTERNAL: + return internalAuthProcessor.auth(exchange, chain); + } + } catch (RenException e) { + return response(exchange, new Result<>().error(e.getCode(), e.getMessage())); + } catch (Exception e) { + return response(exchange, new Result<>().error(e.getMessage())); } return chain.filter(exchange); @@ -100,40 +94,23 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory internalAuthUrls; /** - * 需要外部认证的url + * 对外部应用开放的url列表 */ - private List externalAuthUrls; + private List externalOpenUrls; /** * 不处理token,直接通过 diff --git a/epmet-gateway/src/main/resources/bootstrap.yml b/epmet-gateway/src/main/resources/bootstrap.yml index 750440f69f..ad761dc7fc 100644 --- a/epmet-gateway/src/main/resources/bootstrap.yml +++ b/epmet-gateway/src/main/resources/bootstrap.yml @@ -439,7 +439,7 @@ epmet: - /data/report/** # 外部应用认证,使用AccessToken等头进行认证 - externalAuthUrls: + externalOpenUrls: - /data/report/test/test - /data/report/screen/** - /data/report/kcscreen/**