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. 39
      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. 81
      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.ExceptionUtils;
import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.utils.Result;
import com.epmet.filter.CpProperty;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -41,9 +44,30 @@ public class ExternalAuthProcessor extends AuthProcessor {
@Autowired @Autowired
private ExtAppMD5AuthProcessor md5AuthProcessor; private ExtAppMD5AuthProcessor md5AuthProcessor;
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Autowired
private CpProperty cpProperty;
@Override @Override
public Mono<Void> auth(ServerWebExchange exchange, GatewayFilterChain chain) { 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 token = headers.getFirst(ACCESS_TOKEN_HEADER_KEY);
String appId = headers.getFirst(APP_ID_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); String authType = headers.getFirst(APP_ID_AUTY_TYPE_KEY);
if (StringUtils.isAnyBlank(token, appId)) { 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:{}", 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)) { } else if (APP_AUTH_TYPE_MD5.equals(authType)) {
md5AuthProcessor.auth(appId, token, StringUtils.isNotBlank(ts) ? new Long(ts) : null, exchange); md5AuthProcessor.auth(appId, token, StringUtils.isNotBlank(ts) ? new Long(ts) : null, exchange);
} else { } else {
throw new RenException(EpmetErrorCode.OPER_EXTERNAL_APP_AUTH_ERROR.getCode(), "未知的认证类型"); throw new RenException(EpmetErrorCode.OPER_EXTERNAL_APP_AUTH_ERROR.getCode(), "未知的外部认证类型");
} }
} catch (RenException e) { } catch (RenException e) {
return response(exchange, new Result<>().error(e.getCode(), e.getMsg())); return response(exchange, new Result<>().error(e.getCode(), e.getMsg()));

39
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.security.dto.TokenDto;
import com.epmet.commons.tools.utils.CpUserDetailRedis; import com.epmet.commons.tools.utils.CpUserDetailRedis;
import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.utils.Result;
import com.epmet.filter.CpProperty;
import com.epmet.jwt.JwtTokenUtils; import com.epmet.jwt.JwtTokenUtils;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils; 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.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -36,6 +38,11 @@ public class InternalAuthProcessor extends AuthProcessor {
@Autowired @Autowired
private CpUserDetailRedis cpUserDetailRedis; private CpUserDetailRedis cpUserDetailRedis;
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Autowired
private CpProperty cpProperty;
@Override @Override
public Mono<Void> auth(ServerWebExchange exchange, GatewayFilterChain chain) { public Mono<Void> auth(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
@ -82,14 +89,16 @@ public class InternalAuthProcessor extends AuthProcessor {
} }
} }
// 校验token if (needAuth(requestUri)) {
if (StringUtils.isBlank(token)) { // 校验token
return response(exchange,new Result<>().error(EpmetErrorCode.ERR10005.getCode(),EpmetErrorCode.ERR10005.getMsg())); if (StringUtils.isBlank(token)) {
} return response(exchange, new Result<>().error(EpmetErrorCode.ERR10005.getCode(), EpmetErrorCode.ERR10005.getMsg()));
try { }
validateTokenDto(baseTokenDto, token); try {
} catch (RenException e) { validateTokenDto(baseTokenDto, token);
return response(exchange,new Result<>().error(e.getCode(),e.getMsg())); } catch (RenException e) {
return response(exchange, new Result<>().error(e.getCode(), e.getMsg()));
}
} }
// 添加header // 添加header
@ -116,6 +125,20 @@ public class InternalAuthProcessor extends AuthProcessor {
return chain.filter(exchange); 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 * 从请求中获取token
* @param request * @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";
}

81
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.AppClientConstant;
import com.epmet.commons.tools.constant.Constant; import com.epmet.commons.tools.constant.Constant;
import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.EpmetErrorCode;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.utils.Result; 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.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -40,16 +43,6 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
private Logger logger = LoggerFactory.getLogger(getClass()); 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 @Autowired
private InternalAuthProcessor internalAuthProcessor; private InternalAuthProcessor internalAuthProcessor;
@ -79,16 +72,17 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
String authType = getAuthType(request); String authType = getAuthType(request);
switch (authType) { try {
case AUTH_TYPE_EXTERNAL: switch (authType) {
return externalAuthProcessor.auth(exchange, chain); case AuthTypeConstant.AUTH_TYPE_EXTERNAL:
case AUTH_TYPE_INTERNAL: return externalAuthProcessor.auth(exchange, chain);
return internalAuthProcessor.auth(exchange, chain); case AuthTypeConstant.AUTH_TYPE_INTERNAL:
case AUTH_TYPE_NO_NEED: return internalAuthProcessor.auth(exchange, chain);
break; }
default: } catch (RenException e) {
return response(exchange, new Result<>().error(EpmetErrorCode.ERR401.getCode(), return response(exchange, new Result<>().error(e.getCode(), e.getMessage()));
EpmetErrorCode.ERR401.getMsg())); } catch (Exception e) {
return response(exchange, new Result<>().error(e.getMessage()));
} }
return chain.filter(exchange); return chain.filter(exchange);
@ -100,40 +94,23 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
* @return * @return
*/ */
private String getAuthType(ServerHttpRequest request) { private String getAuthType(ServerHttpRequest request) {
String requestUri = request.getPath().pathWithinApplication().value(); //String requestUri = request.getPath().pathWithinApplication().value();
boolean existsInInternal = false; // 是否在外部认证列表中(外部认证列表中的url,是对外部应用开放的,只有在这个列表中的url才对外部应用开放)
boolean existsInExternal = false; //boolean inExtAuthPaths = false;
//
for (String url : cpProperty.getInternalAuthUrls()) { //for (String url : cpProperty.getExternalAuthUrls()) {
if (antPathMatcher.match(url, requestUri)) { // if (antPathMatcher.match(url, requestUri)) {
existsInInternal = true; // inExtAuthPaths = true;
} // }
} //}
for (String url : cpProperty.getExternalAuthUrls()) { if (StringUtils.isNotBlank(request.getHeaders().getFirst(TokenHeaderKeyConstant.ACCESS_TOKEN_HEADER_KEY))) {
if (antPathMatcher.match(url, requestUri)) { // url对外部应用开放,并且头里面有AccessToken,那么走外部应用认证
existsInExternal = true; return AuthTypeConstant.AUTH_TYPE_EXTERNAL;
}
}
if (!existsInInternal && !existsInExternal) {
// 既不再内部认证url,也不在外部认证url,那么不需要认证
return AUTH_TYPE_NO_NEED;
}
// 内部认证
if (StringUtils.isNotBlank(getHeader(request, Constant.AUTHORIZATION_HEADER))
&& existsInInternal) {
return AUTH_TYPE_INTERNAL;
}
if (StringUtils.isNotBlank(getHeader(request, Constant.ACCESS_TOKEN_HEADER))
&& existsInExternal) {
return 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; private List<String> internalAuthUrls;
/** /**
* 需要外部认证的url * 对外部应用开放的url列表
*/ */
private List<String> externalAuthUrls; private List<String> externalOpenUrls;
/** /**
* 不处理token直接通过 * 不处理token直接通过

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

@ -439,7 +439,7 @@ epmet:
- /data/report/** - /data/report/**
# 外部应用认证,使用AccessToken等头进行认证 # 外部应用认证,使用AccessToken等头进行认证
externalAuthUrls: externalOpenUrls:
- /data/report/test/test - /data/report/test/test
- /data/report/screen/** - /data/report/screen/**
- /data/report/kcscreen/** - /data/report/kcscreen/**

Loading…
Cancel
Save