package com.epmet.auth; 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 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.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 外部应用认证 */ @Component public class ExternalAuthProcessor extends AuthProcessor { private Logger logger = LoggerFactory.getLogger(getClass()); // 头s public static final String AUTHORIZATION_TOKEN_HEADER_KEY = "Authorization"; public static final String ACCESS_TOKEN_HEADER_KEY = "AccessToken"; public static final String APP_ID_HEADER_KEY = "appId"; public static final String APP_ID_TIMESTAMP_KEY = "ts"; public static final String APP_ID_CUSTOMER_ID_KEY = "CustomerId"; public static final String APP_ID_AUTY_TYPE_KEY = "AuthType"; // 认证方式 public static final String APP_AUTH_TYPE_JWT = "jwt"; public static final String APP_AUTH_TYPE_MD5 = "md5"; @Autowired private ExtAppJwtAuthProcessor jwtAuthProcessor; @Autowired private ExtAppMD5AuthProcessor md5AuthProcessor; @Override public Mono auth(ServerWebExchange exchange, GatewayFilterChain chain) { HttpHeaders headers = exchange.getRequest().getHeaders(); String token = headers.getFirst(ACCESS_TOKEN_HEADER_KEY); String appId = headers.getFirst(APP_ID_HEADER_KEY); String ts = headers.getFirst(APP_ID_TIMESTAMP_KEY); String customerId = headers.getFirst(APP_ID_CUSTOMER_ID_KEY); String authType = headers.getFirst(APP_ID_AUTY_TYPE_KEY); if (StringUtils.isAnyBlank(token, appId)) { throw new RenException("请求头中的AccessToken和AppId不能为空"); } logger.info("外部应用请求认证拦截Aspect执行,appId:{}, token:{}, ts:{}, customerId:{}, authType:{}", appId, token, ts, customerId, authType); // 没传authType或者传的jwt都用jwtprocessor处理 try { if (StringUtils.isBlank(authType) || APP_AUTH_TYPE_JWT.equals(authType)) { jwtAuthProcessor.auth(appId, token, StringUtils.isNotBlank(ts) ? new Long(ts) : null, exchange); } 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(), "未知的认证类型"); } } catch (RenException e) { return response(exchange, new Result<>().error(e.getCode(), e.getMsg())); } catch (Exception e) { logger.error("外部应用请求认证发生未知错误:" + ExceptionUtils.getErrorStackTrace(e)); return response(exchange, new Result<>().error("外部应用请求认证发生未知错误")); } return chain.filter(exchange); } }