Browse Source

Merge branch 'dev_externalappauth' into dev_temp

# Conflicts:
#	epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppJwtTokenUtils.java
dev_shibei_match
wxz 5 years ago
parent
commit
f50739d655
  1. 13
      epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/aspect/ExternalAppRequestAuthAspect.java
  2. 10
      epmet-module/epmet-common-service/common-service-client/src/main/java/com/epmet/dto/form/ExternalAppAuthFormDTO.java
  3. 8
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/constant/ExtAppAuthTypeConstant.java
  4. 4
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/controller/ExternalAppController.java
  5. 3
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/service/ExternalAppAuthService.java
  6. 108
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/service/impl/ExternalAppAuthServiceImpl.java
  7. 73
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppAuthProcessor.java
  8. 61
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppJwtAuthProcessor.java
  9. 10
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppJwtTokenUtils.java
  10. 42
      epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppMD5AuthProcessor.java

13
epmet-commons/epmet-commons-extapp-auth/src/main/java/com/epmet/commons/extappauth/aspect/ExternalAppRequestAuthAspect.java

@ -37,6 +37,9 @@ public class ExternalAppRequestAuthAspect {
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";
@Autowired
private EpmetCommonServiceOpenFeignClient commonServiceOpenFeignClient;
@ -52,6 +55,9 @@ public class ExternalAppRequestAuthAspect {
HttpServletRequest request = getRequest();
String token = request.getHeader(ACCESS_TOKEN_HEADER_KEY);
String appId = request.getHeader(APP_ID_HEADER_KEY);
String ts = request.getHeader(APP_ID_TIMESTAMP_KEY);
String customerId = request.getHeader(APP_ID_CUSTOMER_ID_KEY);
String authType = request.getHeader(APP_ID_AUTY_TYPE_KEY);
if (StringUtils.isAnyBlank(token, appId)) {
throw new RenException("请求头中的token和appId不能为空");
@ -62,6 +68,11 @@ public class ExternalAppRequestAuthAspect {
ExternalAppAuthFormDTO form = new ExternalAppAuthFormDTO();
form.setAppId(appId);
form.setToken(token);
form.setAuthType(authType);
if (StringUtils.isNotBlank(ts)) {
// 将字符串转化为时间
form.setTs(new Long(ts));
}
Result<ExternalAppAuthResultDTO> result = commonServiceOpenFeignClient.externalAppAuth(form);
if (result == null) {
throw new RenException("调用服务进行外部应用认证,返回null");
@ -84,7 +95,7 @@ public class ExternalAppRequestAuthAspect {
if (parameters[i].getType() == ExternalAppRequestParam.class) {
ExternalAppRequestParam requestParam = (ExternalAppRequestParam) point.getArgs()[i];
requestParam.setAppId(appId);
requestParam.setCustomerId(authResult.getCustomerId());
requestParam.setCustomerId(authResult.getCustomerId() == null ? customerId : authResult.getCustomerId());
}
}
}

10
epmet-module/epmet-common-service/common-service-client/src/main/java/com/epmet/dto/form/ExternalAppAuthFormDTO.java

@ -15,4 +15,14 @@ public class ExternalAppAuthFormDTO {
*/
private String token;
/**
* 时间戳
*/
private Long ts;
/**
* 认证类型md5jwt
*/
private String authType;
}

8
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/constant/ExtAppAuthTypeConstant.java

@ -0,0 +1,8 @@
package com.epmet.constant;
public interface ExtAppAuthTypeConstant {
String JWT = "jwt";
String MD5 = "md5";
}

4
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/controller/ExternalAppController.java

@ -42,12 +42,14 @@ public class ExternalAppController {
public Result<ExternalAppAuthResultDTO> auth(@RequestBody ExternalAppAuthFormDTO formDTO) {
String appId = formDTO.getAppId();
String token = formDTO.getToken();
Long ts = formDTO.getTs();
String authType = formDTO.getAuthType();
if (StringUtils.isAnyBlank(token, appId)) {
throw new RenException("请求头中的token和appId不能为空");
}
logger.info("外部应用请求认证拦截Aspect。appId:{}, token:{}", appId, token);
ExternalAppAuthResultDTO auth = externalAppAuthService.auth(appId, token);
ExternalAppAuthResultDTO auth = externalAppAuthService.auth(appId, token, ts, authType);
return new Result<ExternalAppAuthResultDTO>().ok(auth);
}

3
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/service/ExternalAppAuthService.java

@ -1,10 +1,9 @@
package com.epmet.service;
import com.epmet.dto.result.ExternalAppAuthResultDTO;
import com.epmet.dto.result.ExternalAppResultDTO;
public interface ExternalAppAuthService {
ExternalAppAuthResultDTO auth(String appId, String token);
ExternalAppAuthResultDTO auth(String appId, String token, Long ts, String authType);
}

108
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/service/impl/ExternalAppAuthServiceImpl.java

@ -1,19 +1,10 @@
package com.epmet.service.impl;
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.redis.RedisKeys;
import com.epmet.commons.tools.redis.RedisUtils;
import com.epmet.dao.ExternalAppDao;
import com.epmet.dao.ExternalAppSecretDao;
import com.epmet.constant.ExtAppAuthTypeConstant;
import com.epmet.dto.result.ExternalAppAuthResultDTO;
import com.epmet.dto.result.ExternalAppResultDTO;
import com.epmet.entity.ExternalAppEntity;
import com.epmet.entity.ExternalAppSecretEntity;
import com.epmet.service.ExternalAppAuthService;
import com.epmet.utils.externalapp.ExtAppJwtTokenUtils;
import io.jsonwebtoken.Claims;
import com.epmet.utils.externalapp.ExtAppJwtAuthProcessor;
import com.epmet.utils.externalapp.ExtAppMD5AuthProcessor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -26,90 +17,23 @@ public class ExternalAppAuthServiceImpl implements ExternalAppAuthService {
private static Logger logger = LoggerFactory.getLogger(ExternalAppAuthServiceImpl.class);
@Autowired
private RedisUtils redisUtils;
private ExtAppJwtAuthProcessor jwtAuthProcessor;
@Autowired
private ExtAppJwtTokenUtils jwtTokenUtils;
@Autowired
private ExternalAppSecretDao externalAppSecretDao;
@Autowired
private ExternalAppDao externalAppDao;
private int diffMillins = 1000 * 60 * 5;
private ExtAppMD5AuthProcessor md5AuthProcessor;
@Override
public ExternalAppAuthResultDTO auth(String appId, String token) {
String secret;
if (StringUtils.isBlank(secret = getTokenByAppId(appId))) {
return fillAuthResult(false, String.format("根据AppId:%s没有找到对应的秘钥", appId), null);
public ExternalAppAuthResultDTO auth(String appId, String token, Long ts, String authType) {
// 没传或者传的jwt都用jwtprocessor处理
if (StringUtils.isBlank(authType) || ExtAppAuthTypeConstant.JWT.equals(authType)) {
return jwtAuthProcessor.auth(appId, token, ts);
} else if (ExtAppAuthTypeConstant.MD5.equals(authType)) {
return md5AuthProcessor.auth(appId, token, ts);
} else {
ExternalAppAuthResultDTO rst = new ExternalAppAuthResultDTO();
rst.setMessage("错误的认证类型");
rst.setSuccess(false);
return rst;
}
Claims claim;
try {
claim = jwtTokenUtils.getClaimByToken(token, secret);
} catch (Exception e) {
String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
logger.error("解析token失败:{}", errorStackTrace);
return fillAuthResult(false, "解析token失败", null);
}
String appIdIn = (String)claim.get("appId");
String customerId = (String)claim.get("customerId");
Long timestamp = (Long)claim.get("ts");
//校验时间戳,允许5分钟误差
if (StringUtils.isAnyBlank(appIdIn, customerId) || timestamp == null) {
logger.error("access token不完整。{},{},{}", appIdIn, customerId, timestamp);
return fillAuthResult(false, "access token不完整。", null);
}
// TODO
// if (!validTimeStamp(timestamp)) {
// logger.error("服务器存在时差过大,请求被拒绝", appId, appIdIn);
// return fillAuthResult(false, "服务器存在时差过大,请求被拒绝", null);
// }
if (!appId.equals(appIdIn)) {
logger.error("AppId不对应,token外部的:{}, token内部解析出来的:{}", appId, appIdIn);
return fillAuthResult(false, "Header中的AppId不匹配", null);
}
return fillAuthResult(true, "解析成功", customerId);
}
private boolean validTimeStamp(Long timestamp) {
long now = System.currentTimeMillis();
// System.out.println(new Date(timestamp));
if (Math.abs(now - timestamp) > diffMillins) {
return false;
}
return true;
}
/**
* 通过APP ID查询对应的秘钥
* @param appId
* @return
*/
public String getTokenByAppId(String appId) {
String secret = (String)redisUtils.get(RedisKeys.getExternalAppSecretKey(appId));
if (StringUtils.isBlank(secret)) {
ExternalAppSecretEntity secretEntity = externalAppSecretDao.getSecretsByAppId(appId);
if (secretEntity == null) {
return null;
}
secret = secretEntity.getSecret();
redisUtils.set(RedisKeys.getExternalAppSecretKey(appId), secret);
}
return secret;
}
public ExternalAppAuthResultDTO fillAuthResult(Boolean result, String message, String customerId) {
ExternalAppAuthResultDTO authResult = new ExternalAppAuthResultDTO();
authResult.setSuccess(result);
authResult.setMessage(message);
authResult.setCustomerId(customerId);
return authResult;
}
}

73
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppAuthProcessor.java

@ -0,0 +1,73 @@
package com.epmet.utils.externalapp;
import com.epmet.commons.tools.redis.RedisKeys;
import com.epmet.commons.tools.redis.RedisUtils;
import com.epmet.dao.ExternalAppSecretDao;
import com.epmet.dto.result.ExternalAppAuthResultDTO;
import com.epmet.entity.ExternalAppSecretEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 外部应用认证处理器父类
*/
public abstract class ExtAppAuthProcessor {
@Autowired
private RedisUtils redisUtils;
@Autowired
private ExternalAppSecretDao externalAppSecretDao;
private int diffMillins = 1000 * 60 * 5;
public abstract ExternalAppAuthResultDTO auth(String appId, String token, Long ts);
/**
* 通过APP ID查询对应的秘钥
* @param appId
* @return
*/
public String getTokenByAppId(String appId) {
String secret = (String)redisUtils.get(RedisKeys.getExternalAppSecretKey(appId));
if (StringUtils.isBlank(secret)) {
ExternalAppSecretEntity secretEntity = externalAppSecretDao.getSecretsByAppId(appId);
if (secretEntity == null) {
return null;
}
secret = secretEntity.getSecret();
redisUtils.set(RedisKeys.getExternalAppSecretKey(appId), secret);
}
return secret;
}
/**
* 时间戳校验
* @param timestamp
* @return
*/
protected boolean validTimeStamp(Long timestamp) {
long now = System.currentTimeMillis();
if (Math.abs(now - timestamp) > diffMillins) {
return false;
}
return true;
}
/**
* 封装结果
* @param result
* @param message
* @param customerId
* @return
*/
public ExternalAppAuthResultDTO fillAuthResult(Boolean result, String message, String customerId) {
ExternalAppAuthResultDTO authResult = new ExternalAppAuthResultDTO();
authResult.setSuccess(result);
authResult.setMessage(message);
authResult.setCustomerId(customerId);
return authResult;
}
}

61
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppJwtAuthProcessor.java

@ -0,0 +1,61 @@
package com.epmet.utils.externalapp;
import com.epmet.commons.tools.exception.ExceptionUtils;
import com.epmet.dto.result.ExternalAppAuthResultDTO;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* jwt 认证处理器
*/
@Component
public class ExtAppJwtAuthProcessor extends ExtAppAuthProcessor {
private static Logger logger = LoggerFactory.getLogger(ExtAppJwtAuthProcessor.class);
@Autowired
private ExtAppJwtTokenUtils jwtTokenUtils;
public ExternalAppAuthResultDTO auth(String appId, String token, Long ts) {
String secret;
if (StringUtils.isBlank(secret = getTokenByAppId(appId))) {
return fillAuthResult(false, String.format("根据AppId:%s没有找到对应的秘钥", appId), null);
}
Claims claim;
try {
claim = jwtTokenUtils.getClaimByToken(token, secret);
} catch (Exception e) {
String errorStackTrace = ExceptionUtils.getErrorStackTrace(e);
logger.error("解析token失败:{}", errorStackTrace);
return fillAuthResult(false, "解析token失败", null);
}
String appIdIn = (String)claim.get("appId");
String customerId = (String)claim.get("customerId");
Long timestamp = (Long)claim.get("ts");
//校验时间戳,允许5分钟误差
if (StringUtils.isAnyBlank(appIdIn, customerId) || timestamp == null) {
logger.error("access token不完整。{},{},{}", appIdIn, customerId, timestamp);
return fillAuthResult(false, "access token不完整。", null);
}
// TODO 暂时去掉时间差判断
//if (!validTimeStamp(timestamp)) {
// logger.error("服务器存在时差过大,请求被拒绝");
// return fillAuthResult(false, "服务器存在时差过大,请求被拒绝", null);
//}
if (!appId.equals(appIdIn)) {
logger.error("AppId不对应,token外部的:{}, token内部解析出来的:{}", appId, appIdIn);
return fillAuthResult(false, "Header中的AppId不匹配", null);
}
return fillAuthResult(true, "解析成功,认证成功", customerId);
}
}

10
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppJwtTokenUtils.java

@ -75,11 +75,13 @@ public class ExtAppJwtTokenUtils {
public static void genToken() {
HashMap<String, Object> claim = new HashMap<>();
claim.put("appId", "acc4ad66c82a7b46e741364b4c62dce2");
claim.put("customerId", "b09527201c4409e19d1dbc5e3c3429a1");
claim.put("ts", System.currentTimeMillis() - 1000 * 60 * 4);
claim.put("appId", "2c448b7da527055fbeebb628f8d3dcb0");
claim.put("customerId", "c1");
long ts = System.currentTimeMillis() - 1000 * 60 * 4;
System.out.println("时间戳:" + ts);
claim.put("ts", ts);
String abc = new ExtAppJwtTokenUtils().createToken(claim, "612d304095c50369c3ef06e490f05779eeb8f19ff16566c73aeafafc5fa01970");
String abc = new ExtAppJwtTokenUtils().createToken(claim, "d4b73db4cf8e46ef99fa1f95149c2791ef2396fded114dd09e406cbce83fc88a");
System.out.println(abc);
}

42
epmet-module/epmet-common-service/common-service-server/src/main/java/com/epmet/utils/externalapp/ExtAppMD5AuthProcessor.java

@ -0,0 +1,42 @@
package com.epmet.utils.externalapp;
import com.epmet.commons.tools.utils.Md5Util;
import com.epmet.dto.result.ExternalAppAuthResultDTO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* md5 认证处理器
*/
@Component
public class ExtAppMD5AuthProcessor extends ExtAppAuthProcessor {
private static Logger logger = LoggerFactory.getLogger(ExtAppMD5AuthProcessor.class);
public ExternalAppAuthResultDTO auth(String appId, String token, Long ts) {
if (ts == null) {
return fillAuthResult(false, "需要传入时间戳参数", null);
}
String secret;
if (StringUtils.isBlank(secret = getTokenByAppId(appId))) {
return fillAuthResult(false, String.format("根据AppId:%s没有找到对应的秘钥", appId), null);
}
String localDigest = Md5Util.md5(secret.concat(":") + ts);
if (!localDigest.equals(token)) {
// 调用方生成的摘要跟本地生成的摘要不匹配
return fillAuthResult(false, "签名不匹配,认证失败", null);
}
// TODO 暂时去掉时间差判断
//if (!validTimeStamp(ts)) {
// logger.error("服务器存在时差过大,请求被拒绝");
// return fillAuthResult(false, "服务器存在时差过大,请求被拒绝", null);
//}
return fillAuthResult(true, "签名匹配,认证成功", null);
}
}
Loading…
Cancel
Save