package com.epmet.auth; import com.epmet.commons.security.jwt.JwtUtils; import com.epmet.commons.security.sign.openapi.OpenApiSignUtils; 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 io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; 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; /** * 外部应用认证处理器:来平台token的方式 */ @Component public class ExtAppFetchTokenAuthProcessor extends ExtAppAuthProcessor { @Autowired private JwtUtils jwtTokenUtils; @Autowired private RedisUtils redisUtils; @Override public void auth(String appId, String token, Long ts, ServerWebExchange exchange) { // 这种方式不需要其他平台传appId,因此我们自己从redis中取 appId = (String) redisUtils.get(RedisKeys.getOpenApiAccessTokenKey(token)); // 1.token过期校验 if (StringUtils.isBlank(appId)) { throw new RenException(EpmetErrorCode.OPEN_API_SIGN_TOKEN_EXPIRED.getCode(), EpmetErrorCode.OPEN_API_SIGN_TOKEN_EXPIRED.getMsg()); } String secret = getSecret(appId); if (jwtTokenUtils.isTokenExpired(jwtTokenUtils.getExpiration(token, secret))) { throw new RenException(EpmetErrorCode.OPEN_API_SIGN_TOKEN_EXPIRED.getCode(), EpmetErrorCode.OPEN_API_SIGN_TOKEN_EXPIRED.getMsg()); } // 2.验签 // 验签暂时放到具体接口中 //openApiSignUtils.checkSign(); // 2. 获取claims Claims claims = jwtTokenUtils.getClaimByToken(token, secret); appId = claims.get("appId", String.class); if (!StringUtils.isBlank(appId)) { ServerHttpRequest.Builder mutate = exchange.getRequest().mutate(); mutate.header("appId", appId); exchange.mutate().request(mutate.build()).build(); } } /** * @Description 获取秘钥 * @return * @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("fetchToken方式的外部应用认证,获取secret失败"); } String secret = result.getData(); if (StringUtils.isBlank(secret)) { throw new RenException("fetchToken方式的外部应用认证,获取secret失败"); } return secret; } }