Browse Source

调整内外部认证的逻辑,外部应用全部需要认证,urls中的是开放的

dev_shibei_match
wxz 5 years ago
parent
commit
77f4f05fb7
  1. 30
      epmet-gateway/src/main/java/com/epmet/auth/ExternalAuthProcessor.java
  2. 27
      epmet-gateway/src/main/java/com/epmet/auth/InternalAuthProcessor.java
  3. 8
      epmet-gateway/src/main/java/com/epmet/constant/AuthTypeConstant.java
  4. 6
      epmet-gateway/src/main/java/com/epmet/constant/TokenHeaderKeyConstant.java
  5. 71
      epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java
  6. 4
      epmet-gateway/src/main/java/com/epmet/filter/CpProperty.java
  7. 2
      epmet-gateway/src/main/resources/bootstrap.yml

30
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<Void> 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()));

27
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<Void> auth(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
@ -82,14 +89,16 @@ public class InternalAuthProcessor extends AuthProcessor {
}
}
if (needAuth(requestUri)) {
// 校验token
if (StringUtils.isBlank(token)) {
return response(exchange,new Result<>().error(EpmetErrorCode.ERR10005.getCode(),EpmetErrorCode.ERR10005.getMsg()));
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()));
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

8
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";
}

6
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";
}

71
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<CpA
private Logger logger = LoggerFactory.getLogger(getClass());
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
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";
@Autowired
private CpProperty cpProperty;
@Autowired
private InternalAuthProcessor internalAuthProcessor;
@ -79,16 +72,17 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
String authType = getAuthType(request);
try {
switch (authType) {
case AUTH_TYPE_EXTERNAL:
case AuthTypeConstant.AUTH_TYPE_EXTERNAL:
return externalAuthProcessor.auth(exchange, chain);
case AUTH_TYPE_INTERNAL:
case AuthTypeConstant.AUTH_TYPE_INTERNAL:
return internalAuthProcessor.auth(exchange, chain);
case AUTH_TYPE_NO_NEED:
break;
default:
return response(exchange, new Result<>().error(EpmetErrorCode.ERR401.getCode(),
EpmetErrorCode.ERR401.getMsg()));
}
} 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<CpA
* @return
*/
private String getAuthType(ServerHttpRequest request) {
String requestUri = request.getPath().pathWithinApplication().value();
boolean existsInInternal = false;
boolean existsInExternal = false;
//String requestUri = request.getPath().pathWithinApplication().value();
for (String url : cpProperty.getInternalAuthUrls()) {
if (antPathMatcher.match(url, requestUri)) {
existsInInternal = true;
}
}
for (String url : cpProperty.getExternalAuthUrls()) {
if (antPathMatcher.match(url, requestUri)) {
existsInExternal = true;
}
}
if (!existsInInternal && !existsInExternal) {
// 既不再内部认证url,也不在外部认证url,那么不需要认证
return AUTH_TYPE_NO_NEED;
}
// 内部认证
if (StringUtils.isNotBlank(getHeader(request, Constant.AUTHORIZATION_HEADER))
&& existsInInternal) {
return AUTH_TYPE_INTERNAL;
}
// 是否在外部认证列表中(外部认证列表中的url,是对外部应用开放的,只有在这个列表中的url才对外部应用开放)
//boolean inExtAuthPaths = false;
//
//for (String url : cpProperty.getExternalAuthUrls()) {
// if (antPathMatcher.match(url, requestUri)) {
// inExtAuthPaths = true;
// }
//}
if (StringUtils.isNotBlank(getHeader(request, Constant.ACCESS_TOKEN_HEADER))
&& existsInExternal) {
return AUTH_TYPE_EXTERNAL;
if (StringUtils.isNotBlank(request.getHeaders().getFirst(TokenHeaderKeyConstant.ACCESS_TOKEN_HEADER_KEY))) {
// url对外部应用开放,并且头里面有AccessToken,那么走外部应用认证
return AuthTypeConstant.AUTH_TYPE_EXTERNAL;
}
return AUTH_TYPE_UNKNOW;
return AuthTypeConstant.AUTH_TYPE_INTERNAL;
}
/**

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

@ -23,9 +23,9 @@ public class CpProperty {
private List<String> internalAuthUrls;
/**
* 需要外部认证的url
* 对外部应用开放的url列表
*/
private List<String> externalAuthUrls;
private List<String> externalOpenUrls;
/**
* 不处理token直接通过

2
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/**

Loading…
Cancel
Save