package com.epmet.auth; import com.epmet.commons.security.jwt.JwtUtils; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.redis.RedisKeys; import com.epmet.commons.tools.redis.RedisUtils; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.utils.SpringContextUtils; import com.epmet.feign.EpmetCommonServiceOpenFeignClient; import com.epmet.openapi.constant.InClusterHeaderKeys; import com.epmet.openapi.constant.RequestParamKeys; import io.jsonwebtoken.Claims; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import java.util.Date; /** * 外部应用认证处理器:来平台token的方式 */ @Component public class ExtAppTakeTokenAuthProcessor extends ExtAppAuthProcessor { @Autowired private JwtUtils jwtTokenUtils; @Autowired private RedisUtils redisUtils; @Override public void auth(String appId, String token, Long ts, ServerWebExchange exchange) { String secret = getSecret(appId); // 1.过期验证 String accessTokenInCache = redisUtils.getString(RedisKeys.getOpenApiAccessTokenKey(appId)); Date expiration = jwtTokenUtils.getExpiration(token, secret); if (StringUtils.isBlank(accessTokenInCache) || expiration == null || jwtTokenUtils.isTokenExpired(expiration) ) { throw new RenException(EpmetErrorCode.OPEN_API_TOKEN_EXPIRED.getCode(), EpmetErrorCode.OPEN_API_TOKEN_EXPIRED.getMsg()); } // 2.验签 // 验签暂时放到具体接口中,不放在gateway //openApiSignUtils.checkSign(); // 2. 获取claims Claims claims = jwtTokenUtils.getClaimByToken(token, secret); String appIdInAccessToken = claims.get(RequestParamKeys.APP_ID, String.class); if (!appId.equals(appIdInAccessToken)) { // 参数列表的appId和token中封装的不一致 throw new RenException(EpmetErrorCode.OPEN_API_PARAMS_APPID_DIFF.getCode(), EpmetErrorCode.OPEN_API_PARAMS_APPID_DIFF.getMsg()); } // 3.将app_id放入header中 ServerHttpRequest.Builder mutate = exchange.getRequest().mutate(); mutate.header(InClusterHeaderKeys.APP_ID, new String[]{appId}); exchange.mutate().request(mutate.build()).build(); } /** * @return * @Description 获取秘钥 * @author wxz * @date 2021.03.23 14:12 */ private String getSecret(String appId) { EpmetCommonServiceOpenFeignClient commonService = SpringContextUtils.getBean(EpmetCommonServiceOpenFeignClient.class); Result result = commonService.getSecret(appId); if (result == null || !result.success()) { throw new RenException("TakeToken方式的外部应用认证,获取secret失败"); } String secret = result.getData(); if (StringUtils.isBlank(secret)) { throw new RenException("TakeToken方式的外部应用认证,获取secret失败"); } return secret; } }