ali idcard verify

This commit is contained in:
ran.shang
2025-06-17 18:39:28 +08:00
parent f4a4fb9c76
commit 94a5f85c65
14 changed files with 413 additions and 26 deletions

View File

@@ -8,7 +8,9 @@ public enum FactorVerificationSourceTypeEnum {
FXQ("放心签", 1),
CL("创蓝", 2),
SYS("系统", 3);
SYS("系统", 3),
ALI("阿里", 4),
;
private final String desc;

View File

@@ -40,8 +40,6 @@ import lombok.extern.slf4j.Slf4j;
@SuppressWarnings("rawtypes,unchecked")
public abstract class AbstractVerify<T extends FactorVerificationDTO> implements IVerify<T>, ITopicMqHandler<T>{
private static final Integer DEFAULT_TYPE = FactorVerificationSourceTypeEnum.CL.getType();
static final Map<Integer, FactorVerificationSourceService> SOURCE_SERVICE_MAP = Maps.newConcurrentMap();
/**
@@ -97,14 +95,9 @@ public abstract class AbstractVerify<T extends FactorVerificationDTO> implements
protected T syncBeforeVerify(T t) {
// 认证源根据配置文件不同调用不同SDK 1放心签、2创蓝
String source = EnvironmentUtils.getProperty("alita.authenticationSource");
int authenticationSource = DEFAULT_TYPE;
int authenticationSource = FactorVerificationSourceTypeEnum.CL.getType();
try {
authenticationSource = Integer.parseInt(source);
//如果不是这两种认证源,用默认的源
if (!(FactorVerificationSourceTypeEnum.CL.getType().equals(authenticationSource)
|| FactorVerificationSourceTypeEnum.FXQ.getType().equals(authenticationSource))) {
authenticationSource = DEFAULT_TYPE;
}
} catch (NumberFormatException e) {
//doNothing
}

View File

@@ -0,0 +1,67 @@
package com.newyetai.alitaforward.verification.source.ali;
import cn.hutool.json.JSONUtil;
import com.newyetai.alitaforward.verification.constants.FactorVerificationSourceTypeEnum;
import com.newyetai.alitaforward.verification.dto.FactorVerificationDTO;
import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
import com.newyetai.alitaforward.verification.source.FactorVerificationSourceService;
import com.newyetai.alitaforward.verification.source.ali.mapstruct.AliVerifyMapMapper;
import com.newyetai.common.AlitaResult;
import com.newyetai.common.constant.AuthStatusEnum;
import com.newyetai.common.util.JsonUtils;
import com.newyetai.sdk.ali.dto.IdCardReq;
import com.newyetai.sdk.ali.dto.IdCardRes;
import com.newyetai.sdk.ali.service.AliVerifyService;
import com.newyetai.sdk.common.constant.SdkConstants;
import java.util.Objects;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@SuppressWarnings("unchecked")
public class ALiVerifySourceServiceImpl implements FactorVerificationSourceService {
@Resource(name = AliVerifyService.BEAN_ID)
private AliVerifyService aliVerifyService;
@Override
public RealNameTwoFactorVerificationDTO twoVerify(RealNameTwoFactorVerificationDTO verificationDTO) {
IdCardReq requestDTO = AliVerifyMapMapper.INSTANCE.toDTO(verificationDTO);
log.info("二要素认证:{}", JSONUtil.toJsonStr(requestDTO));
AlitaResult<IdCardRes> result = aliVerifyService.verify(requestDTO);
handlerResult(result, verificationDTO);
return verificationDTO;
}
private void handlerResult(AlitaResult<?> result, FactorVerificationDTO verificationDTO) {
verificationDTO.setInvokeData(JsonUtils.toJsonString(result));
AuthStatusEnum targetStatus = null;
if (SdkConstants.SDK_INVOKE_NOT_REACH_CODE.equals(result.getCode())) {
// 接口调起失败,未拿到返回结果,视为未调起
verificationDTO.setFailReason("调用异常,未调起第三方");
} else {
if (Boolean.TRUE.equals(result.getSuccess())) {
targetStatus = AuthStatusEnum.AUTH_SUCCESS;
} else {
targetStatus = AuthStatusEnum.AUTH_FAIL;
verificationDTO.setFailReason(result.getMsg());
}
}
if (Objects.nonNull(targetStatus)) {
verificationDTO.setStatus(targetStatus.getType());
}
}
@Override
public FactorVerificationSourceTypeEnum getSourceType() {
return FactorVerificationSourceTypeEnum.ALI;
}
}

View File

@@ -0,0 +1,24 @@
package com.newyetai.alitaforward.verification.source.ali.mapstruct;
import com.newyetai.alitaforward.verification.dto.RealNameTwoFactorVerificationDTO;
import com.newyetai.sdk.ali.dto.IdCardReq;
import com.newyetai.sdk.chuanglan.dto.RealNameTwoBaseRequestDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AliVerifyMapMapper {
AliVerifyMapMapper INSTANCE = Mappers.getMapper(AliVerifyMapMapper.class);
@Mappings(value = {
@Mapping(target = "name", source = "dto.realName"),
@Mapping(target = "idcard", source = "dto.cardNo")
})
IdCardReq toDTO(RealNameTwoFactorVerificationDTO dto);
}

View File

@@ -17,7 +17,7 @@ public class StrUtils {
/**
* 大驼峰转小驼峰(AaBb -> aaBb)
*
*
* @param upperCamel
* @return
* @author sr on 2021-02-03
@@ -30,7 +30,7 @@ public class StrUtils {
/**
* 驼峰转蛇形(AaBb -> aa_bb)
*
*
* @param upperCamel
* @return
* @author sr on 2021-02-03
@@ -57,6 +57,17 @@ public class StrUtils {
* @author sr on 2022-02-10
*/
public static String buildAscQueryValue(Object paramData) {
return buildAscQueryValue(paramData, true, null);
}
/**
* @param paramData 参数
* @param normal 是否正常(p1=v1&p2=v2)
* @param split 特殊分隔符(v1分隔符v2)
* @return
* @author sr on 2024-11-18
*/
public static String buildAscQueryValue(Object paramData, boolean normal, String split) {
Map<String, Object> paramDataMap = null;
if (paramData instanceof Map) {
paramDataMap = paramDataMap;
@@ -82,12 +93,52 @@ public class StrUtils {
}
StringBuilder paramstr = new StringBuilder();
for (Entry<String, Object> entry : parameters.entrySet()) {
paramstr.append(entry.getKey()).append(CommonConstants.EQUAL)
.append(entry.getValue()).append(CommonConstants.AND);
if (normal) {
paramstr.append(entry.getKey()).append(CommonConstants.EQUAL)
.append(entry.getValue()).append(CommonConstants.AND);
} else {
paramstr.append(entry.getValue()).append(split);
}
}
return paramstr.substring(0, paramstr.length() - 1);
}
/**
* 构建参数字符串(xx=**&xx=**)
* @param paramData
* @return
* @author sr on 2024-11-18
*/
public static String buildQueryValue(Object paramData) {
Map<String, Object> paramDataMap = null;
if (paramData instanceof Map) {
paramDataMap = paramDataMap;
} else {
try {
paramDataMap = JsonUtils.objToClassObj(paramData, Map.class);
} catch (Exception e) {
throw new BusinessException("参数对象格式错误");
}
}
if (paramDataMap == null || paramDataMap.isEmpty()) {
return null;
}
StringBuilder paramstr = new StringBuilder();
for (Entry<String, Object> entry : paramDataMap.entrySet()) {
Object value = entry.getValue();
if (value != null) {
paramstr.append(entry.getKey()).append(CommonConstants.EQUAL)
.append(entry.getValue()).append(CommonConstants.AND);
}
}
if (paramstr.length() == 0) {
return null;
}
return paramstr.substring(0, paramstr.length() - 1);
}
/**
* 不为空/空字符串/"null"字符串
* @param str
@@ -97,5 +148,5 @@ public class StrUtils {
public static boolean isNotNull(String str) {
return StringUtils.isNotBlank(str) && !"null".equals(str);
}
}

View File

@@ -0,0 +1,45 @@
package com.newyetai.sdk.ali.config;
import com.newyetai.sdk.chuanglan.config.ChuangLanCommonProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Builder.Default;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = AliProperties.PREFIX)
@Data
@Component
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AliProperties {
/** 配置前缀 */
public static final String PREFIX = "ali";
public static final String IDCARD_PREFIX = PREFIX + ".idcard";
/** 二要素配置 */
private IdcardProperties idcard;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class IdcardProperties {
/** 是否启用 **/
@Default
private Boolean enable = Boolean.FALSE;
/** 次数限制 **/
private Long numLimit;
private String url;
/** */
private String appcode;
}
}

View File

@@ -0,0 +1,27 @@
package com.newyetai.sdk.ali.dto;
import com.newyetai.sdk.common.dto.ISdkRequest;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.core.ParameterizedTypeReference;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class IdCardReq implements ISdkRequest<VerifyRes<IdCardRes>> {
private static ParameterizedTypeReference<VerifyRes<IdCardRes>> type = new ParameterizedTypeReference<VerifyRes<IdCardRes>>() {
};
private String name;
private String idcard;
@Override
public ParameterizedTypeReference<VerifyRes<IdCardRes>> getResponseType() {
return type;
}
}

View File

@@ -0,0 +1,27 @@
package com.newyetai.sdk.ali.dto;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class IdCardRes implements Serializable {
/** code为200 data才会有值,400参数格式错误 */
public static final Integer SUC_CODE = 200;
/** 1.不一致 0.一致 */
public static final Integer SUC_RESULT = 0;
private String birthday;
private Integer result;
private String address;
private String orderNo;
private String sex;
private String desc;
}

View File

@@ -0,0 +1,17 @@
package com.newyetai.sdk.ali.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VerifyRes<T> {
private String msg;
private String success;
private Integer code;
private T data;
}

View File

@@ -0,0 +1,14 @@
package com.newyetai.sdk.ali.service;
import com.newyetai.common.AlitaResult;
import com.newyetai.sdk.ali.dto.IdCardReq;
import com.newyetai.sdk.ali.dto.IdCardRes;
public interface AliVerifyService {
String BEAN_ID = "sdk.aliVerifyService";
String MOCK_BEAN_ID = "mock.aliVerifyService";
AlitaResult<IdCardRes> verify(IdCardReq req);
}

View File

@@ -0,0 +1,78 @@
package com.newyetai.sdk.ali.service.impl;
import com.newyetai.common.AlitaResult;
import com.newyetai.common.annotation.CheckAndMock;
import com.newyetai.common.util.JsonUtils;
import com.newyetai.common.util.StrUtils;
import com.newyetai.sdk.ali.config.AliProperties;
import com.newyetai.sdk.ali.config.AliProperties.IdcardProperties;
import com.newyetai.sdk.ali.dto.IdCardReq;
import com.newyetai.sdk.ali.dto.IdCardRes;
import com.newyetai.sdk.ali.dto.VerifyRes;
import com.newyetai.sdk.ali.service.AliVerifyService;
import com.newyetai.sdk.common.constant.SdkConstants;
import com.newyetai.sdk.common.dto.DefaultSdkInvokeLogDTO;
import com.newyetai.sdk.common.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Service(AliVerifyService.BEAN_ID)
public class AliVerifyServiceImpl implements AliVerifyService {
private static RestTemplate restTemplate = HttpUtils.restTemplate;
@Autowired
private AliProperties aliProperties;
@Override
@CheckAndMock(mockClass = MockAliVerifyServiceImpl.class,
propertyPrefix = AliProperties.IDCARD_PREFIX)
public AlitaResult<IdCardRes> verify(IdCardReq req){
return this.verify(req, aliProperties.getIdcard());
}
public static AlitaResult<IdCardRes> verify(IdCardReq req, IdcardProperties idcardProperties){
VerifyRes<IdCardRes> res = null;
try {
try {
// 构建请求头
HttpHeaders header = new HttpHeaders();
header.add("Authorization", "APPCODE " + idcardProperties.getAppcode());
header.add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
// 发送请求
HttpEntity<?> requestEntity = new HttpEntity(StrUtils.buildQueryValue(req), header);
ResponseEntity<VerifyRes<IdCardRes>> result = restTemplate.exchange(idcardProperties.getUrl(),
HttpMethod.POST, requestEntity, req.getResponseType());
res = result.getBody();
} catch (Exception e) {
log.info("invoke error :{}", e);
return AlitaResult.error(SdkConstants.SDK_HTTP_INVOKE_ERROR_CODE, e.getMessage());
}
try {
if (IdCardRes.SUC_CODE.equals(res.getCode()) && IdCardRes.SUC_RESULT.equals(res.getData().getResult())) {
return AlitaResult.success(res.getData());
}
return AlitaResult.error(SdkConstants.SDK_HTTP_INVOKE_RESPONSE_FAIL_CODE,
res.getCode() + res.getData().getDesc());
} catch (Exception e) {
return AlitaResult.error(SdkConstants.SDK_RESPONSE_CONVERT_ERROR_CODE,
e.getMessage());
}
} finally {
log.info("invoke:{}",
JsonUtils
.toJsonString(
DefaultSdkInvokeLogDTO.builder().requestData(req).responseData(res)
.build()));
}
}
}

View File

@@ -0,0 +1,19 @@
package com.newyetai.sdk.ali.service.impl;
import com.newyetai.common.AlitaResult;
import com.newyetai.sdk.ali.dto.IdCardReq;
import com.newyetai.sdk.ali.dto.IdCardRes;
import com.newyetai.sdk.ali.service.AliVerifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service(AliVerifyService.MOCK_BEAN_ID)
public class MockAliVerifyServiceImpl implements AliVerifyService {
@Override
public AlitaResult<IdCardRes> verify(IdCardReq req) {
log.info("ali idcard mock...");
return AlitaResult.success(IdCardRes.builder().result(IdCardRes.SUC_RESULT).build());
}
}